我认为你错过了如何在测试中使用模拟对象的重点......
您正在做的是模拟 ProductRepository 对象,同时对其进行测试。这没有多大意义;你不应该模拟你正在测试的对象。
假设您有一个要测试的类 ProductService,它依赖于另一个类 IProductRepository。当您测试 ProductService 时,您需要模拟依赖项 IProductRepository。这使您可以完全控制被测类与其(模拟)依赖项之间的交互。
当您这样做时,您的断言将基于您期望被测类 ProductService 执行的操作。例如,如果您使用类似的方法调用 ProductService productService.GetProductById(1)
,您将期望 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);
我的语法可能不正确,但希望该示例能够跨越几点:
- 不要模拟被测系统
- 模拟依赖项
- 将您的断言基于被测系统的职责,而不是依赖关系