Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何用假货来模仿服务?_C#_.net_Unit Testing_Fakeiteasy - Fatal编程技术网

C# 如何用假货来模仿服务?

C# 如何用假货来模仿服务?,c#,.net,unit-testing,fakeiteasy,C#,.net,Unit Testing,Fakeiteasy,我有一个简单的实体框架存储库,可以通过服务调用进行访问(请参阅 查看相关课程)。我正在尝试测试服务,如下所示 public class ProductServiceTests { private IProductService sut; private IProductRepository productRepo; [Fact] public async Task CanCallGetProductById() { //Arrange

我有一个简单的实体框架存储库,可以通过服务调用进行访问(请参阅 查看相关课程)。我正在尝试测试服务,如下所示

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);
    }
}
 sut = new Fake<IProductService>().FakedObject;
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);
    }
}
然而,这种方法也有问题:对函数
wait sut.GetProductById(id)
的调用实际上并不调用任何被测试的代码。事实上,如果我抛出一个异常,测试仍然通过

    public async Task<Product> GetProductById(int id)
    {
        throw new NotImplementedException();
        //return await _productRepository.GetAll().FirstOrDefaultAsync(x => x.Id == id);
    }
ProductService
的实现如下

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);
    }
}
 sut = new Fake<IProductService>().FakedObject;
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);
    }
}
公共类ProductService:IPProductService
{
私有只读IPProductRepository\u productRepository;
公共产品服务(IPProductRepository productRepository)
{
_productRepository=productRepository;
}
公共异步任务GetProductById(int id)
{
//抛出新的NotImplementedException();
return await\u productRepository.GetAll()
.FirstOrDefaultAsync(x=>x.Id==Id);
}
}

使用赝品(或模拟或其他东西)帮助测试服务的一般方法是模拟被测系统的合作者(在本例中为
IPProductService
),并使用真实的被测系统(如果您不使用真实的被测系统,则您的系统不是“被测”)。因此,使用原始代码并进行改编,您可能需要这样的内容:

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


        // This is different from your example. 
        // The idea is to configure `productRepo`, not `sut`.
        // Also, I don't know the interface for `IProductRepository`,
        // so you'll have to adjust this call to match `GetAll`
        A.CallTo(() => productRepo.GetAll(id)).Returns(new [] {expectation});

        // Act
        var result = await sut.GetProductById(id);

        // Assert
        Assert.Equal(id, result.Id);
    }
}
公共类ProductServiceTests
{
私人IPS服务sut;
私人iproductrepo;
[事实]
公共异步任务CanCallGetProductById()
{
//安排
productRepo=new Fake().FakedObject;
sut=新产品服务(productRepo);
var-id=1;
var期望=新产品{Id=Id};
//这与您的示例不同。
//其思想是配置'productRepo',而不是'sut'。
//另外,我不知道“IPProductRepository”的接口,
//因此,您必须调整此调用以匹配“GetAll”`
A.CallTo(()=>productRepo.GetAll(id)).Returns(new[]{expectation});
//表演
var result=wait sut.GetProductById(id);
//断言
Assert.Equal(id,result.id);
}
}

非常感谢您的解决方案。不幸的是,我无法根据我的代码修改您的答案(但我想这是因为我的无知)。实际上,我的存储库没有实现
GetProductById
方法。它只实现了一个
GetAllProducts
方法,`IPProductService`使用该方法通过其
id
查找产品。我在新编辑的问题中添加了此信息。我没有说过存储库实现了
GetProductById
。我说要配置
productRepo.GetAll
。如果您配置
GetAll()
,我的方法应该有效,但需要注意的是,您需要让它返回一个实现
IDbAsyncQueryProvider
的类,这可能很难实现。我不是EntityFramework用户,因此建议遵循Ben Hall的建议。不过,由于您是新加入FIE的,首先练习测试不使用EF的代码变体可能会有所帮助。再次感谢您的帮助。我会按照你的建议去做,我相信我会解决的。