Относитесь к Интеграционным Тестам Как к Внешним Потребителям
В ASP.NET Core есть отличная поддержка для написания интеграционных тестов. Они используются, например, при создании API, чтобы убедиться, что вы не нарушаете публичные контракты при разработке.
Допустим, у нас есть контроллер, выдающий информацию о гамбургере:
public class HamburgersController : ControllerBaseМы создаём интеграционный тест, чтобы убедиться, что конечная точка работает должным образом, например, выдаёт 200 OK. И ещё один тест, который проверяет, что тело ответа содержит название гамбургера (тестирование контракта):
{
[HttpGet("{name}")]
public ActionResult<HamburgerDto> Get(string name)
{
var burger = new HamburgerDto();
// получение информации
// …
return new OkObjectResult(burger);
}
}
public class HamburgerDto
{
public string Name { get; set; }
}
public async Task ShouldReturnBurgerName()Тест работает отлично, но у него есть одна серьезная проблема. Выше мы говорили, что этот тест предназначен, чтобы проверить, не нарушаем ли мы контракт. Представьте, что нам нужно переименовать свойство
{
// запрос к контроллеру
// …
var burger = await JsonSerializer
.DeserializeAsync<HamburgerDto>(
response,
new JsonSerializerOptions(JsonSerializerDefaults.Web));
burger.Name.ShouldBe("Big Mac");
}
Name в HamburgerName (критическое изменение в контракте). Если мы используем инструмент рефакторинга, который автоматически переименует свойство во всех местах, где оно используется, вышеуказанный тест обновится автоматически и все равно будет проходить:…Проблема в том, что мы десериализуем ответ в класс
burger.HamburgerName.ShouldBe("Big Mac");
…
HamburgerDto. Мы привязываем наш интеграционный тест к деталям реализации нашего API. Вместо десериализации ответа в
HamburgerDto мы можем использовать JsonDocument:public async Task ShouldReturnBurgerName()Теперь, если бы мы изменили свойство Name на HamburgerName, вышеуказанный тест не прошёл бы. Это делает тест более похожим на внешнего потребителя нашего API. Используя такой подход, мы можем предотвратить внесение критических изменений в производственный код.
{
// запрос к контроллеру
// …
var burger = await
JsonDocument.ParseAsync(response);
burger.RootElement
.GetProperty("name").GetString()
.ShouldBe("Big Mac");
}
Источник: https://josef.codes/treat-you-integration-tests-as-external-consumers/