考虑以下服务 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/