设置模拟无法正常工作(returns 执行的存储库方法空值)

Setup mock not working fine (returns exectuted repository method null value)

我在为添加实体设置模拟时遇到了一些问题。如果我想获取 entity/entites,我的模拟设置工作正常,但当我想要创建(添加)时。我设置了创建方法,结果返回 null。

P.S AddProductAsync 我怀疑,这个方法可能不行,虽然我检查了调试,有调用方法

 public class ProductServiceTests
{
    private Mock<IProductRepository> _productMockRepo = new Mock<IProductRepository>();
    private ProductService _sut;

    public ProductServiceTests()
    {
        _sut = new ProductService(_productMockRepo.Object);
    }

这是我的测试方法

[Fact]
    public async Task AddProduct_ShouldReturnProduct_WhenInputDataIsCorrect()
    {
        
        //Arrange
        var productId = Guid.NewGuid().ToString();
        var actualProduct = new ProductModel
        {
            Name = "test",
            Price = 1,
            Category = Category.Foods,
            Quantity = 2
        };
        
        var addingProduct = new Product
        {
            Name = actualProduct.Name,
            Price = actualProduct.Price,
            Category = actualProduct.Category,
            Quantity = actualProduct.Quantity
        };
        
        _productMockRepo.Setup(x => x.AddProductAsync(addingProduct))
            .ReturnsAsync(addingProduct);
        
        //Act
        var result = await _sut.AddProductAsync(actualProduct);
        
        //Assert
        
        Assert.Equal(actualProduct.Name, result.Name);
        _productMockRepo.Verify(x => x.AddProductAsync(addingProduct), Times.Once);
        

    }
}

_sut 是我的服务,_productMockRepo 是我的模拟存储库

我使用 NuGet packadge“Moq”进行测试

谢谢)

问题是预期被设置为使用 addingProduct,一个特定的实例

_productMockRepo.Setup(x => x.AddProductAsync(addingProduct))
        .ReturnsAsync(addingProduct);

但是在进行测试时,它会在被测成员中创建另一个实例

var result = await _sut.AddProductAsync(actualProduct);

我只能假设它做了类似于这里所做的事情

var addingProduct = new Product {
    Name = actualProduct.Name,
    Price = actualProduct.Price,
    Category = actualProduct.Category,
    Quantity = actualProduct.Quantity
};

因为测试对象(即:ProductService.AddProductAsync(Product product))没有显示。

因为它不是设置中使用的实际实例,所以默认情况下模拟将 return null。

在这种情况下,在设置预期行为期间放松参数匹配

//...

_productMockRepo
    .Setup(x => x.AddProductAsync(It.IsAny<Product>())) //<-- loosen expected match
    .ReturnsAsync((Product p) => p); //<-- return the argument that was passed to the member

//...

并更改验证表达式以检查通过的内容

_productMockRepo.Verify(x => x.AddProductAsync(It.Is<Product>(p => addingProduct.Name == p.Name && ... )), Times.Once);

参考:MOQ Quickstart - Matching Arguments