模拟存储库方法未通过验证测试

Mock repository method failed verify test

我在 .NET Core 应用程序中使用 Moq 框架和 xUnit。我有一个存储库的模拟

public interface IItemRepository<T>
{
    string Add(T entity);
}

我想测试 class 的方法,它正在使用这个存储库

public DefaultCartService(IItemRepository<CartItem> cartRepository)
{
    _cartRepository = cartRepository;
}

public Task<GenericResponse<string>> AddItem(CartItem model)
{
   var result = new GenericResponse<string>();

    try
    {
        result.Response = _cartRepository.Add(cartItem);
    }
    catch(Exception ex)
    {
        result.Status = false;
        result.Error = ex.Message;
    }

    return Task.FromResult(result);
}

这是一个通用响应Class,用于包装存储库结果

public class GenericResponse<T>
{
    public bool Status { get; set; } = true;
    public T Response { get; set; }
    public string Error { get; set;
    }
}

我是这样为仓库预置Mock并调用方法的

[Fact]
public  void AddItem_WorkingTest()
{
    //creating mock
    var mock = new Mock<IItemRepository<CartItem>>();

    //setting a method
    mock.Setup(x => x.Add(new CartItem())).Returns("SomeGuidValue");

    //creating input param
    CartItemInputModelDTO inputModel = new CartItem() {BuyerId = "232", ProductId = "35435" };

    //creating service class instance and passing repository mock
    var _service = new DefaultCartService(_cartRepository.Object);

    //calling method
    var result =  _service.AddItem(inputModel).Result.Response;

    //verifying that mocks method been called
    mock.Verify(x => x.Add(new CartItem()), Times.AtLeastOnce);
}

结果,我的测试失败了,因为从未调用过存储库。而且我不明白为什么,因为我设置了没有要调用的停止方法 测试结果

Moq.MockException : Expected invocation on the mock at least once, but was never performed: x => x.Add(CartItem)
Performed invocations: Mock<IItemRepository<CartItem>:2 (x): No invocations performed.

在设置中使用 It.IsAny<CartItem>()。当前设置将无法工作,因为测试中通过的实例不是设置中使用的实例。

此外,如果测试 returns Task 派生结果的成员,则进行异步测试

[Fact]
public  async Task AddItem_WorkingTest() {
    //creating mock
    var mock = new Mock<IItemRepository<CartItem>>();

    //setting a method
    mock.Setup(x => x.Add(It.IsAny<CartItem>())).Returns("SomeGuidValue");

    //creating input param
    var inputModel = new CartItem() {BuyerId = "232", ProductId = "35435" };

    //creating service class instance and passing repository mock
    var _service = new DefaultCartService(mock.Object);

    //calling method
    var result =  await _service.AddItem(inputModel);;

    //verifying that mocks method been called
    mock.Verify(x => x.Add(It.IsAny<CartItem>()), Times.AtLeastOnce);
}

如果你想验证传递给模拟的实例的成员,那么使用 It.Is<CartItem>() 和谓词

例如

//... omitted for brevity

mock.Verify(x => x.Add(It.Is<CartItem>(_ => 
    _.BuyerId == inputModel.BuyerId 
    && _.ProductId == inputModel.ProductId)), Times.AtLeastOnce);

引用Moq Quickstart