单元测试,模拟 - 简单案例:服务 - 存储库

raf*_*fek 12 c# service unit-testing mocking repository

考虑以下服务块:

public class ProductService : IProductService {

   private IProductRepository _productRepository;

   // Some initlization stuff

   public Product GetProduct(int id) {
      try {
         return _productRepository.GetProduct(id);
      } catch (Exception e) {
         // log, wrap then throw
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

让我们考虑一个简单的单元测试:

[Test]
public void GetProduct_return_the_same_product_as_getProduct_on_productRepository() {
   var product = EntityGenerator.Product();

   _productRepositoryMock.Setup(pr => pr.GetProduct(product.Id)).Returns(product);

   Product returnedProduct = _productService.GetProduct(product.Id);

   Assert.AreEqual(product, returnedProduct);

   _productRepositoryMock.VerifyAll();
}
Run Code Online (Sandbox Code Playgroud)

起初看起来这个测试还可以.但是让我们改变一下我们的服务方法:

public Product GetProduct(int id) {
   try {
      var product = _productRepository.GetProduct(id);

      product.Owner = "totallyDifferentOwner";

      return product;
   } catch (Exception e) {
      // log, wrap then throw
   }
}
Run Code Online (Sandbox Code Playgroud)

如何重写一个给定的测试,它通过第一个服务方法传递,而第二个服务方法失败?

你如何处理这种简单的场景?

提示1:给定的测试是错误的coz产品,而returnProduct实际上是相同的参考.

提示2:实现平等成员(object.equals)不是解决方案.

提示3:至于现在,我使用AutoMapper创建了Product实例(expectedProduct)的克隆 - 但我不喜欢这个解决方案.

提示4:我没有测试SUT不做某事.我正在尝试测试SUT DOES返回从存储库返回的相同对象.

Ste*_*ger 9

就个人而言,我不会在意这一点.测试应该确保代码正在执行您的意图.很难测试代码没有做什么,在这种情况下我不会打扰.

测试实际上应该是这样的:

[Test]
public void GetProduct_GetsProductFromRepository() 
{
   var product = EntityGenerator.Product();

   _productRepositoryMock
     .Setup(pr => pr.GetProduct(product.Id))
     .Returns(product);

   Product returnedProduct = _productService.GetProduct(product.Id);

   Assert.AreSame(product, returnedProduct);
}
Run Code Online (Sandbox Code Playgroud)

我的意思是,这是你正在测试的一行代码.