【发布时间】:2020-08-10 10:47:11
【问题描述】:
我有一个通过服务调用访问的简单实体框架存储库(请参阅 this UML diagram 查看相关课程)。我正在尝试按如下方式测试服务
public class ProductServiceTests
{
private IProductService sut;
private IProductRepository productRepo;
[Fact]
public async Task CanCallGetProductById()
{
//Arrange
productRepo = new Fake<IProductRepository>().FakedObject;
sut = new ProductService(productRepo);
var id = 1;
var expectation = new Product { Id = id };
A.CallTo(() => sut.GetProductById(id)).Returns(expectation);
// Act
var result = await sut.GetProductById(id);
// Assert
Assert.Equal(id, result.Id);
}
}
但是,这会导致以下异常System.ArgumentException : Object 'ProductService' of type ProductService is not recognized as a fake object.
这意味着我可能需要使用以下服务的模拟
sut = new Fake<IProductService>().FakedObject;
然而,这种方法也存在问题:对函数await sut.GetProductById(id) 的调用实际上并没有调用任何被测代码。确实,如果我抛出异常,测试仍然通过
public async Task<Product> GetProductById(int id)
{
throw new NotImplementedException();
//return await _productRepository.GetAll().FirstOrDefaultAsync(x => x.Id == id);
}
编辑 经过一些故障排除后,我意识到,实际上,我试图测试的代码实际上并没有达到。比如下面的测试
A.CallTo(() => productRepo.GetAll()).MustHaveHappened();
失败并显示Product.GetAll() Expected to find it once or more but no calls were made to the fake object.的消息
请有人解释我应该如何解决这个错误?
编辑
IProductRepository 和 IProductService 定义如下:
public interface IProductRepository
{
IQueryable<Product> GetAll();
}
public interface IProductService
{
Task<Product> GetProductById(int id);
}
而ProductService的实现方式如下
public class ProductService : IProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<Product> GetProductById(int id)
{
//throw new NotImplementedException();
return await _productRepository.GetAll()
.FirstOrDefaultAsync(x => x.Id == id);
}
}
【问题讨论】:
标签: c# .net unit-testing fakeiteasy