服务层上的Moq测试错误为空

时间:2014-04-18 20:43:31

标签: c# .net moq

如何更正以下测试?

[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();            
}

我得到以下内容:

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

As Requested这是被调用的GetEmployeeByUserName()函数:

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.)
}

3 个答案:

答案 0 :(得分:1)

您需要为模拟的FindEmployeeByUsername()方法设定种子:

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

否则它不会返回预期的对象,而是在EmployeeService中调用。

答案 1 :(得分:1)

由于您编辑了问题以显示GetEmployeeByUserName的行为,因此现在很容易解释您的测试失败的原因。

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

在这里,您设置了一个期望FindEmployeeByUsername(string)重载将被调用,但随后您继续使用FindEmployeeByUsername(Employee)重载。 Moq设置用于特定的重载,因此当调用该方法时,模拟的服务找不到匹配的设置。如果没有匹配的设置,模拟将返回Employee类型(null)的默认值,或者抛出异常,具体取决于您选择的MockBehavior

在更新的测试中,您通过设置实际使用的重载来修复此问题。

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

使用像GetEmployeeByUserName这样的简单方法,模拟依赖关系和单元测试,它看起来像很多开销。你的测试基本上是什么,

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

这是一个重要的断言吗?这取决于你自己决定。然而,随着服务方法的复杂性增加,能够隔离依赖关系并测试其交互将变得越来越有价值。

答案 2 :(得分:0)

而不是使用我认为令人困惑的多个存储库。我简化了它,它现在有效!除了我还不确定这如何帮助我更好地编码。我用这个完成了什么? (我是测试/ Moq /集成测试的新手......等等。)我真的很想答案......对此...

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);
}