c# - 单元测试,模拟 - 简单案例 : Service - Repository

标签 c# unit-testing service mocking repository

考虑以下服务 block :

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

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

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

乍一看好像这个测试没问题。但是让我们稍微改变一下我们的服务方法:

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

      product.Owner = "totallyDifferentOwner";

      return product;
   } catch (Exception e) {
      // log, wrap then throw
   }
}

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

您如何处理这种简单场景?

提示 1: 给定的测试是错误的,因为产品和 returnedProduct 实际上是相同的引用。

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

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

提示 4: 我不是在测试 SUT 不做某事。我正在尝试测试 SUT 是否返回与从存储库返回的对象相同的对象。

最佳答案

就我个人而言,我不会关心这个。测试应确保代码按照您的意图进行。 很难测试哪些代码没有在做什么,在这种情况下我不会费心。

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

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

我的意思是,这是您正在测试的一行代码。

关于c# - 单元测试,模拟 - 简单案例 : Service - Repository,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2793171/

相关文章:

c# - 你如何在 C# 中读取 NASA .hgt 文件?

javascript - 将 C# 中的字符串变量传递给 javascript 函数以在警报框中使用

javascript - 在 asp.net MVC 中打印表格行

c# - 通用 Windows 平台中的 System.Xml.XPath

java - 如何对 getter 和 setter 进行单元测试?

android - Service stopForeground(false) 在不应该的时候移除通知

python单元测试发现

c# - 如何在我的方法中 stub /模拟对基类的调用

java - Android 究竟是如何将AIDL 接口(interface)与Remote Service 联系起来的?

android - ServiceConnection::onServiceConnected 没有被调用,即使 Context::bindService 返回 true?