C#单元测试使用Moq.dll进行模拟

时间:2013-06-26 13:00:07

标签: c# unit-testing moq

我的测试用例总是失败,告诉我哪里错了,代码在下面

public class EmployeeService
{
    private readonly IRepository _repository;

    public EmployeeService(IRepository repository)
    {
        _repository = repository;
    }

    public bool SaveEmployeeData(Employee employee,bool isSaveNeeded)
    {
        bool result = false;
        try
        {
            if (isSaveNeeded)
            {
                result= _repository.Save(employee);
            }
        }
        catch (Exception ex)
        {
            throw new Exception();
        }
        return result;
    }
}

我的测试用例是

[TestMethod()]
public void SaveEmployeeDataTest()
{
    var a = new Mock<IRepository>();
    a.Setup(s => s.Save(new Employee())).Returns(true).Verifiable();
    var result = new EmployeeService(a.Object).SaveEmployeeData(new Employee(), true);
    Assert.IsTrue(result);
}

总是失败。

3 个答案:

答案 0 :(得分:4)

使用It.IsAny<Employee>设置保存方法参数

a.Setup(s => s.Save(It.IsAny<Employee>())).Returns(true).Verifiable();

您的测试无法工作的原因是您有两个不同的员工实例 - 一个用于模拟设置,另一个传递给SaveEmployeeData方法调用。默认情况下,这些实例将通过引用进行比较。 Moq等待具有参考13(例如)的雇员实例的Save方法调用。但是你正在通过参考42传递另一名员工。因此永远不会调用设置。

您还有两个选项

  • 覆盖Equals类的GetHashCodeEmployee方法。因此,Moq将不是通过参考而是通过业务数据来比较员工。
  • 使用完全相同的员工实例进行模拟设置和SaveEmployeeData方法调用(首选方式)

使用同一员工实例:

[TestMethod()]
public void SaveEmployeeDataTest()
{
    var a = new Mock<IRepository>();
    var sameEmployee = new Employee();
    a.Setup(s => s.Save(sameEmployee)).Returns(true).Verifiable();

    var service = new EmployeeService(a.Object);
    var result = service.SaveEmployeeData(sameEmployee, true);
    Assert.IsTrue(result);
}

覆盖平等:

public class Employee
{
    public override bool Equals(object obj)
    {
        Employee other = obj as Employee;
        if (other == null)
            return false;

        return this.Id == other.Id; // for example
    }
}

在这种情况下,您可以保持原样。

答案 1 :(得分:3)

new Employee()每次都会创建一个新的员工实例,一次用于设置Save,另一次用于实际的SaveEmployeeData。因此,提供的员工永远不会满足设置的要求。

要么使用像lazyberezovsky的回答这样的全能方式,要么执行以下操作:

[TestMethod()]
public void SaveEmployeeDataTest()
{
    var a = new Mock<IRepository>();
    var employee = new Employee();
    a.Setup(s => s.Save(employee)).Returns(true).Verifiable();
    var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true);
    Assert.IsTrue(result);
}

因为在设置中使用与实际调用中相同的Employee实例,所以匹配设置并返回正确的结果。

答案 2 :(得分:1)

试试这个 -

[TestMethod()]
public void SaveEmployeeDataTest()
{
    var a = new Mock<IRepository>();
var employee = new Employee();
    a.Setup(s => s.Save(employee)).Returns(true).Verifiable();
    var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true);
    Assert.IsTrue(result);
}

您需要在设置和方法调用中使用相同的员工实例。这将确保验证您使用的是在方法中传递的相同员工实例,而不是在方法中创建或从其他方法返回的内容。