How can the following test be corrected to work?

[TestMethod()]       
public void GetEmployeeProductivityTest()
{
    var mockHR = new Mock<IRepository<Employee>>();
    var mockCMS = new Mock<ICMS_Repository>();

    mockCMS.Setup(repos => repos.FindEmployeeByUsername(It.IsAny<string>())).Verifiable();          

    Employee newEmp = new Employee();
    newEmp.User_Name = "testName";

    var service = new EmployeeService(mockHR.Object,mockCMS.Object);
    var createResult = service.GetEmployeeByUserName(newEmp);

    Assert.AreEqual(newEmp, createResult);
    mockCMS.VerifyAll();            
}

I get the following:

Assert.AreEqual failed. Expected:<Employee>. Actual:<(null)>.

As Requested this is the GetEmployeeByUserName() function being called:

public Employee GetEmployeeByUserName(Employee employee)
{
    return _employeeRespository.Find().ByUserName(employee); <------(Using Strict: Gives me the following:  All invocations on the mock must have a corresponding setup.)
}
有帮助吗?

解决方案

Since you edited your question to show the behaviour of the GetEmployeeByUserName, it's now easy to explain why your test was failing.

mockCMS.Setup(repos => repos.FindEmployeeByUsername(It.IsAny<string>()))

Here you set up an expectation that the FindEmployeeByUsername(string) overload would be called, but then you go on to use the FindEmployeeByUsername(Employee) overload. Moq setups are for specific overloads so when the method is called the mocked service finds no matching setup. If there is no matching setup, the mock either returns the default value for the Employee type (null), or throws an exception, depending on which MockBehavior you chose.

In your updated test, you fixed this by setting up the overload that you actually use.

mockCMS.Setup(repos => repos.FindEmployeeByUsername(It.IsAny<Employee>()))

With simple methods like your GetEmployeeByUserName, mocking the dependencies and unit testing it can seem like a lot of overhead. What your test says is basically,

"when someone calls the GetEmployeeByUserName method on the EmployeeService, 
the service should call the correct method on its repository"

Is this an important thing to assert? That's up to you to decide. As the complexity of your service methods increases, however, being able to isolate the dependencies and test their interactions will become more and more valuable.

其他提示

You need to seed the FindEmployeeByUsername() Method of your mock:

mockCMS.Setup(repos => repos.FindEmployeeByUsername(It.IsAny<string>())).Returns(newEmp);

otherwise it wont return the expected object, while called within the EmployeeService.

Instead of using multiple repositories which I think was confusing. I simplified it and it works now! Except I'm still not sure how this helps me code better. What did I accomplish with this? (I'm new to Testing/Moq/Integration Tests...etc..) I would really like an answer...to this..

public void GetEmployeeUsername_Using_EmployeeClass()
{
    var mockCMS = new Mock<ICMS_Repository>(MockBehavior.Strict);

    Employee newEmp = new Employee();
    newEmp.User_Name = "testName";

    mockCMS.Setup(repos => repos.FindEmployeeByUsername(It.IsAny<Employee>())).Returns(newEmp);

    var service = new EmployeeService(mockCMS.Object);
    var createResult = service.GetEmployeeByUserName(newEmp);

    Assert.AreEqual(newEmp, createResult);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top