如何在 crud 操作中使用 MOQ

How to use MOQ in crud operations

我有一个典型的 CRUD 操作界面(存储库),我想知道有人会如何使用 MOQ.

来测试它

型号

public class Model
{
   public int Id{get;set;}
}

界面

public interface ICrud
{
   Task<IEnumerable<Model>> GetAllAsync();
   Task AddAsync(Model model);
}

服务

public class Service
{
   public ICrud operations;

   Service(ICrud crud){ this.operations=crud;}

   public Task<IEnumerable<Model>> GetAllAsync()=>this.operations.GetAllAsync();
   public Task AddAsync(Model model)=> this.operations.AddAsync(model);
}

单元测试

public class Test
{
   public IEnumerable Seed(){
        yield return new Model {id=3};
        yield return new Model {id =4};
   }
   [Testcase(3)]
   public async Task CanAdd(int id)
   {
         var mock=new Mock<ICrud>();
         var newModel=new Model{ Id=id};
         mock.Setup(x=>x.GetAsync()).ReturnsAsync(Seed);
         mock.Setup(x=>x.AddAsync(newModel));
        //how can i test adding the new model

         var service=new Service(mock.Object);
         var initialList=await service.GetAllAsync();
         //adding
         await service.AddAsync(newModel);
         var finalList=await service.GetAllAsync();

   }
}

我的问题是,如何测试以下场景:

-i check the initial collection
-i call `AddAsync`
-i check to see that the new collection contains the added element.

如何在单元测试中使用 Moq 实现这一目标?

在此场景中,pass case 是被测对象服务正确调用给定模型的依赖操作。

因此,测试应反映出运动时的情况。

使用看起来像

的最小起订量
public async Task Service_Should_AddAsync() {
    //Arrange
    int id = 1;
    var mock = new Mock<ICrud>();
    var newModel = new Model { Id = id };
    mock.Setup(x => x.AddAsync(It.IsAny<Model>())).Returns(Task.CompletedTask);

    var service = new Service(mock.Object);

    //Act
    await service.AddAsync(newModel);

    //Assert
    //verify that the mock was invoked with the given model.
    mock.Verify(x => x.AddAsync(newModel));

}

或者你可以在没有模拟框架的情况下做到这一点。

public class InMemoryCrud : ICrud
{
    public List<Model> Models { get; set; } = new List<Model>();

    public Task<IEnumerable<Model>> GetAllAsync() => return Task.FromResult(Models);        

    public Task AddAsync(Model model)
    {
        Models.Add(model);
        return Task.CompletedTask;
    }
}

public async Task Add_Model() 
{
    var fakeCrud = new InMemoryCrud();
    var service = new Service(fakeCrud);

    var newModel = new Model { Id = 3 };
    await service.AddAsync(newModel);


    var actualModels = await fakeCrud.GetAllAsync();
    var expected = new[]
    {
        new Model { Id = 3 }
    }

    actualModels.Should().BeEquivalentTo(expected); // Pass
}

通过 InMemoryCrud 实现,您可以通过 crud 操作测试"saved" 正确的值。
使用模拟框架,您将测试是否调用了正确的方法。例如,如果在 Service class 中我更改了 Model 给定实例的一些属性 - 测试仍然通过,但错误的数据将在实际应用程序中保存到数据库中。