Я хочу начать использовать FakeItEasy для тестирования запросов. Тесты, которые я хочу написать, должны проверять, возвращаются ли объекты при вызовах HttpGet (получить все и получить по идентификатору)
Контроллер:
public class ToDoController : ControllerBase
{
private readonly IMediator _mediator;
public ToDoController(IMediator mediator) =>
_mediator = mediator;
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<ToDoItem>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<ToDoItem>>> Get()
{
var result = await _mediator.Send(new ToDoItemsQuery(new
AllToDoItems())).ConfigureAwait(false);
if (result != null && result.Any())
{
return result.ToList();
}
throw new InvalidOperationException("TODO: error handling");
}
[HttpGet]
[Route("{id}")]
[Produces("application/json")]
[ProducesResponseType(typeof(ToDoItem), (int)HttpStatusCode.OK)]
public async Task<ActionResult<ToDoItem>> GetById(int itemId)
{
var result = await _mediator
.Send(new ToDoItemsQuery(new ToDoItemById(itemId)))
.ConfigureAwait(false);
if (result != null && result.Any())
{
return result.FirstOrDefault();
}
throw new InvalidOperationException("TODO: error handling");
}
}
}
TestClass:
public class ToDoItemControllerTests : ControllerTestBase
{
private IMediator _mediator;
private ToDoController _sut;
public ToDoItemControllerTests()
{
_mediator = A.Fake<IMediator>();
_sut = new ToDoController(_mediator);
}
[TestMethod]
public async Task GetAllItemsAsync_SuccessTest()
{
A.CallTo(() => _mediator.Send(A<AllToDoItems>._,
A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
var result = await _sut.Get();
Assert.IsNotNull(result);
A.CallTo(() => _mediator).MustHaveHappened();
}
[TestMethod]
public async Task GetItemByIdAsync_SuccessTest()
{
// Arrange
int itemId = 2;
var commandResult =
new List<ToDoItem>
{
new ToDoItem
{
Id = itemId
};
}
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).Returns(commandResult);
// Act
var result = await _sut.GetById(itemId);
// Assert
Assert.IsNotNull(result);
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).MustHaveHappened();
}
}
Итак, в первом тесте я настроил A.CallTo интерфейса IMediatR, чтобы он возвращал 10 ToDoItems. Во время отладки я вижу, что _sut.Get () входит в контроллер, вводя правильный метод / вызов API. _Mediator.Send () в контроллере возвращает Fake IEnumerable (не 10 элементов, которые я установил в первом Call.To в методе тестирования, а перечисление, которое не дает результатов).
Из-за результата .Any () имеет значение false, контроллер выдает исключение InvalidOperationException, и я не могу даже подтвердить результат. IsNotNull ()
Второй тест, который я хочу проверить, если при вызове API возвращается 1 элемент. Я установил (а) itemId типа int для параметра, (b) фиктивный (?) Список с 1 элементом из настройки с itemId и (c) вызов mediatR должен вернуть фиктивный список из (b )
Я выполняю вызов из теста, при отладке я вижу, что вызов await _mediator.Sent () возвращает Fake Ienumerable of ToDoItem, результат не равен нулю, но поскольку result.Any () является ложным, элемент не возвращается, и я получаю еще одно исключение InvalidOperationException
Мне кажется, что мне что-то не хватает в настройке тестов .. Поддельный интерфейс базы данных? Я не хочу рисковать своим контроллером и делать if менее ограничивающим, просто чтобы мой тест прошел
EDIT: даже если я изменю условие if на удаление условия Any, и я вижу, что тест входит в контроллер , возвращая результат «First or Default», тест не проходит при вызове, который должен был произойти. Ожидалось найти его один или несколько раз, но никаких обращений к поддельному объекту не производилось. Я действительно не понимаю, я действительно вижу, как он звонит?!
Я просмотрел GitHub, чтобы найти примеры, но ближе всего я нашел Entities с методами, причем эти методы определены в интерфейсе. Здесь дело обстоит не так.
Поскольку официальная документация не делает меня мудрее, я обращаюсь к SO <3 Заранее спасибо! </p>