我认为你没有理解如何在测试中使用模拟对象的要点...
你所做的是嘲笑一个ProductRepository对象,同时也在测试它。那没什么意义,你不应该嘲笑你正在测试的对象。
假设您有一个需要测试的类ProductService,它依赖于另一个类IProductRepository。当您测试ProductService时,您将希望模拟这个依赖IProductRepository。这将允许您完全控制被测试的类与其(模拟的)依赖之间的交互。
当您这样做时,您的断言将基于您对测试类ProductService的期望。例如,如果您使用类似于productService.GetProductById(1)
的方式调用ProductService,则您将期望ProductService对象仅使用正确的参数调用其IProductRepository方法一次:repository.GetProductById(1)
。您还可以期望ProductService返回IProductRepository给予它的相同对象。无论存储库做什么,那都是ProductService的责任。
话虽如此,你的考试可能更像这样:
//Arrange
int testId = 1;
var fakeProduct = new Product{ Id = testId };
var mockRepo = new Mock<IRepository>();
var productService = new ProductService(mockRepo);
mockRepo.Expect(repo => repo.GetProductById(testId)).Returns(fakeProduct);
//Act
Product returnedProduct = productService.GetProductById(testId);
//Assert
mockRepo.Verify(repo => repo.GetProductById(testId), TimesExactly(1));
Assert.AreEqual(returnedProduct.Id, fakeProduct.Id);
我的语法可能有错,不过希望示例能够表达几个重点:
- Don t mock the system under test
- Mock the dependencies
- Base your assertions on the responsibilities of the system under test, not the dependencies