c# - 在单元测试中模拟依赖关系有什么好处?

标签 c# unit-testing mocking

我正在为我的 Controller 和服务层(C#、MVC)进行单元测试。我正在使用 Moq dll 在单元测试中模拟真实/依赖对象。

但我对模拟依赖项或真实对象有点困惑。让我们以下面的单元测试方法为例:-

[TestMethod]
public void ShouldReturnDtosWhenCustomersFound_GetCustomers ()
{
    // Arrrange 
    var name = "ricky";
    var description = "this is the test";

    // setup mocked dal to return list of customers
    // when name and description passed to GetCustomers method
    _customerDalMock.Setup(d => d.GetCustomers(name, description)).Returns(_customerList);

    // Act
    List<CustomerDto> actual = _CustomerService.GetCustomers(name, description);

    // Assert
    Assert.IsNotNull(actual);
    Assert.IsTrue(actual.Any());

    // verify all setups of mocked dal were called by service
    _customerDalMock.VerifyAll();
}

在上面的单元测试方法中,我模拟了 GetCustomers 方法并返回了一个客户列表。已经定义好了。看起来像下面这样:

List<Customer> _customerList = new List<Customer>
{
    new Customer { CustomerID = 1, Name="Mariya",Description="description"},
    new Customer { CustomerID = 2, Name="Soniya",Description="des"},
    new Customer { CustomerID = 3, Name="Bill",Description="my desc"},
    new Customer { CustomerID = 4, Name="jay",Description="test"},
};

让我们看一下客户模拟对象断言和实际对象断言:-

Assert.AreEqual(_customer.CustomerID, actual.CustomerID);
Assert.AreEqual(_customer.Name, actual.Name);
Assert.AreEqual(_customer.Description, actual.Description);

但在这里我不明白它(在单元测试之上)总是工作正常。意味着我们只是在测试(在断言中)我们通过的或我们正在返回的(在模拟对象中)。我们知道真实/实际对象将始终返回我们传递的列表或对象。

那么在这里做单元测试或者mocking是什么意思呢?

最佳答案

模拟的真正目的是实现真正的隔离。

假设您有一个 CustomerService 类,它依赖于 CustomerRepository。您编写了一些单元测试,涵盖了 CustomerService 提供的功能。他们都通过了。

一个月后,进行了一些更改,突然您的 CustomerServices 单元测试开始失败 - 您需要找出问题所在。

所以你假设:

Because a unit test that tests CustomerServices is failing, the problem must be in that class!!

对吧?错误的!问题可能出在 CustomerServices 或其任何依赖项中,即 CustomerRepository。如果它的任何依赖项失败,则被测类很可能也会失败。

现在想象一个巨大的依赖链:A 依赖于 BB 依赖于 C,. .. Y 取决于 Z。如果在 Z 中引入错误,所有 单元测试都将失败。

这就是为什么您需要将被测类与其依赖项(可能是域对象、数据库连接、文件资源等)隔离开来。您想要测试一个单元

关于c# - 在单元测试中模拟依赖关系有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22783772/

相关文章:

c# - Nlog 可以定位 Azure Log Analytics 吗?

c# - Facebook 和 Twitter/LinkedIn 之间的 OAuth token 差异

unit-testing - 单元测试后 Controller .NET Web Api

c# - 为并发 C# 代码编写单元测试?

Python 模拟方法调用参数显示列表的最后状态

c# - 如何检查输出 DbParameter 的空值?

c# - 将一段代码从 C++ 转换为 C#

unit-testing - FakeItEasy DbSet/IQueryable<T> - Entity Framework 6

java - 如何在单元测试中模拟日历对象以获取特定时间

c# - 如何在单元测试中模拟 DateTime.Now?