Как использовать MOQ в грубых операциях - PullRequest
0 голосов
/ 20 января 2020

У меня типичный интерфейс работы 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 в модульном тесте?

Ответы [ 2 ]

1 голос
/ 20 января 2020

Или вы можете сделать это без фальшивых фреймворков.

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.
С фреймворками фальсификации вы протестируете что правильные методы были вызваны. Например, если в Service классе I изменить некоторые свойства данного экземпляра Model - тесты все равно пройдут, но неправильные данные будут сохранены в базе данных в реальном приложении.

1 голос
/ 20 января 2020

В этом сценарии паролем является то, что испытуемая служба правильно вызывает операцию зависимости с заданной моделью.

Таким образом, тест должен отражать это при выполнении.

Использование MOQ это будет выглядеть как

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...