Я выполняю модульное тестирование логики контроллера в основном проекте asp.net с помощью xUnit и Moq, и у меня возникают проблемы с тестированием метода удаления. Я попытался собрать воедино некоторые идеи из разных руководств и т. д., но все еще борюсь.
Мне удалось проверить, что метод возвращает NoContentResult и NotFoundResponse. Чего мне здесь не хватает, так это теста, чтобы увидеть, что метод удаления действительно удалил элемент из репозитория Bygg.
В этом случае я пытаюсь получить список Bygg, удалить элемент, а затем использовать утверждение, чтобы проверить, содержит ли список только 2 элемента.
к вашему сведению: bygg = здание.
Проект следует шаблону репозитория с общими и пользовательскими репозиториями.
Это метод удаления в контроллере:
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteBygg(int id)
{
try
{
var bygg = await _byggRepository.GetByggByIdAsync(id);
if (bygg == null)
{
return NotFound();
}
await _byggRepository.DeleteByggAsync(bygg);
return NoContent();
}
catch (Exception ex)
{
return StatusCode(500, "Internal Server Error");
}
}
Это метод тестирования:
[Fact]
public async Task DeleteBygg_ExistingIdPassed_RemovesOneItem()
{
// Arrange
_mockRepo.Setup(repo => repo.DeleteByggAsync(It.IsAny<Bygg>()));
_mockRepo.Setup(repo => repo.GetAllByggAsync())
.ReturnsAsync(GetTestBygg());
// Act
var actual = await _controller.GetAllBygg();
var actual2 = actual as OkObjectResult;
var noContentResponse = await _controller.DeleteBygg(1);
// Assert
var items = Assert.IsType<List<Bygg>>(actual2.Value);
Assert.Equal(2, items.Count);
}
Вы издевались над методом DeleteByggAsync, поэтому он ничего не удалит. Возможно, это неправильный сценарий для тестирования. Возможно, вы могли бы просто проверить, был ли вызван DeleteByggAsync с ожидаемым аргументом. Место для проверки фактического удаления — это модульное тестирование byggRepository...
Также похоже, что вы пытаетесь протестировать слишком много вещей в одном модульном тесте.
Чтобы расширить то, что сказал NKosi, вам нужно, чтобы ваши тесты были простыми. В этом случае вам на самом деле все равно, что что-то удалено, потому что ваши тесты DeleteByggAsync должны это проверить. Все, что вам нужно для вашего контроллера, это правильное делегирование вызова. При написании тестов всегда думайте, что можно убрать/упростить
Для информации, это не модульный тест. Это интеграционный тест. Вы находитесь в веб-контексте (контроллере) и тестируете взаимодействие EF и базы данных.





Поскольку вы ничего не возвращаете из метода DeleteBygg, вам нужно просто проверить в тестовом методе, что await _byggRepository.DeleteByggAsync(bygg); правильно вызывается в вашем фактическом методе следующим образом:
[Fact]
public async Task DeleteBygg_ExistingIdPassed_RemovesOneItem()
{
// Arrange
var id = 1;
_mockRepo.Setup(repo => repo.GetByggByIdAsync(id)).ReturnsAsync(new Bygg(){});
_mockRepo.Setup(repo => repo.DeleteByggAsync(It.IsAny<Bygg>())).Returns(Task.CompletedTask);
// Act
await _controller.DeleteBygg(id);
// Assert
_mockRepo.Verify(repo => repo.DeleteByggAsync(It.IsAny<Bygg>()),Times.Once);
}
Я думаю, что теперь у меня есть лучшее представление о том, как проводить модульное тестирование контроллера. Итак, если мне удалось это выяснить, при тестировании логики контроллера мы проверяем правильность выполнения вызовов. Во многих других тестах для контроллера я использовал Assert.IsType<OkObjectResult>(input), например, чтобы проверить, был ли возвращен правильный объектный ответ. А также проверка того, что данные возвращаются там, где это применимо. Кроме того, мне, вероятно, придется также проводить модульное тестирование репозиториев?? Или достаточно протестировать только контроллер? Звучит как реторический вопрос, ха-ха!
Да! Вы также должны написать метод тестирования для методов репозитория. Спасибо
Вы можете просто попробовать убедиться, что макеты получают ожидаемые вызовы при выполнении теста. Нет необходимости получать все и проверять элементы