Как стать автором
Обновить

Как приручить автотестового монстра, или Dependency Injection в автотестах

Уровень сложностиСредний
Время на прочтение15 мин
Количество просмотров7.4K
Всего голосов 14: ↑13 и ↓1+14
Комментарии7

Комментарии 7

IMHO вы неправильно указали формат публикации: она — явный "Туториал", а не "Кейс".

Спасибо за совет. Соглашусь. Поменял)

Через полгода мы обнаружим, что потихоньку пухнет база — не чистятся создаваемые тестами юзеры.

А почему бы не использовать InMemory бд, которая после выполнения тестов ничего не оставляла? Или нужна именно реальная база?

InMemory конечно хорошо. Но, на практике - не всегда возможно.
Пример как раз про то, когда нужна "реальная".

Кажется, что тестовые контейнеры - это ваш выход. Тесты получаются независимые, запускаются в нативном окружении и лишены проблем с инфраструктурой. Всё, что надо сделать разработчику в Windows - включить wsl и поставить docker desktop, в линуксе все из коробки работает

Отличная статья, спасибо!

Вопрос только в хранении Container в базовом классе. Сам метод инициализации через ==? не потокобезопасный, и если у вас сходу запустится несколько тестов, произойдёт несколько вызовов GetContainer, насколько это хорошо?

Потом, как использовать созданные сервиса, если мы хотим их вызвать за пределами тестов? Например, в TestActionAttribute?

Для себя решил держать всё в своём написанном singleton классе, в котором через Instance можно получать все нужные сервиса.

Сам метод инициализации через ==? не потокобезопасный

Да, вы правы, желательно метод инициализации хотя бы в один lock() обернуть. Мы, на своих проектах, это делаем. В данной статье это опустил, дабы не усложнять повествование.

если мы хотим их вызвать за пределами тестов

Конструкцию "container.Register()" не обязательно вызывать один раз. Это можно сделать сколько угодно раз.

По идее, в проекте каждого сервиса/сервисов должен быть свой класс Installer'а. То есть класс, в котором будет описано, как именно устанавливать сервис, и наличие каких зависимостей стоит проверить в подаваемом на вход контейнере, перед вызовом "container.Register()".

В итоге, ContainerInitializer.InitContainer() из статьи, будет представлять из себя перечисление всех тех инсталлеров, которые нужны тестовому проекту.

Такой подход позволит переиспользовать классы Installer'ов где угодно.

Мы, например, переиспользуем одни и те же инсталлеры, вместе с разработчиками, просто обмениваясь nuget-пакетами с описанием контрактов взаимодействия.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий