Pull to refresh

Comments 7

Алексей, спасибо за статью.

Если позволите, хотел бы написать один комментарий про:
Я хотел показать, что никакой таинственной магии в Spring нет, есть просто много «умных» и гибких внутренних мехнизмов, но зная их можно получить полный контроль на тестами и самим приложением.


ИМХО, но вы как раз в статье и показали магию: «всего-то надо реализовать такой-то интерфейс, и добавить вот такую вот аннотацию с таким-то значением».

Если взять в противовес условный go, то там мы бы явно (руками) создали нужные компоненты для теста, и всё явно бы запустили.

Да, гошный подход — более многословный. Но и более явный для человека, кто знает язык программирования, но не конкретный фреймворк.

Я скорее имел в виду, что библиотеки, вроде указанной, не делают ничего магического внутри.


А "реализовать интерфейс" и "добавить аннотацию" это для меня знание инструмента (Спринга). Чтобы им эффективно пользоваться — да, его надо знать. Но зато можно получать преимущества в виде продуктивности после.


В условном Го просто другой подход: вместо абстракций — повторения. Не лучше и не хуже — каждый выберет свой. В общем-то, в Спринг тоже никто не мешает игнорировать библиотеки тестирования — и хоть руками создавать контексты и делать все, что делает Spring Test, получив полный контроль над тестом. Просто потом захочется абстрагировать одну вещь, чтобы не повторять. Потому другую. А потом получится еще один фреймворк для тестирования.

Вот этот механизм кеширования контекстов всё портит. Вернее портит всё тот факт, что этот механизм считает, что контекст нужно пересоздавать при изменении списка конфигураций.


Я вот хочу запустить тесты для той же конфигурации, что и везде, но один бин заменить тестовой реализацией. Делаю я это через создание дополнительной конфигурации, в которой метод, возвращающий новый бин помечен аннотацией Primary. В результате спринг замечает, что список конфигураций тут другой и создаёт новый контекст и, соответственно, поднимает ещё одну базу на случайном порту, что существенно замедляется тесты. Как это красиво решить я чего-то не нашёл.


Единственное, что пока приходит в голову это поднимать встроенную БД ещё до запуска тестов и прокидывать её в конфигурации спринга.

Я вот хочу запустить тесты для той же конфигурации, что и везде, но один бин заменить тестовой реализацией.

В ваших рассуждениях есть логическая ловушка — если заменить один бин это уже не та же конфигурация. Конфигурация в Spring достаточно фундаментальная вещь, которая по-сути описывает приложение.


Вариантов решения есть несколько, зависит от задачи:


  1. Создать базовый класс для тестов с одинаковой конфигурацией. Обычно, это означает тесты для одного и того же компонента (когда замоканы boundaries, об этом еще буду говорить в следующих статьях).
  2. Как уже отмечено — иметь одну базу для всех тестов, если пересоздавать контексты совершенно необходимо.
  3. Подумать над каким-то runtime созданием бинов, но это уже немного воевать с фреймворком.
В ваших рассуждениях есть логическая ловушка — если заменить один бин это уже не та же конфигурация.

Как не называй, суть не поменяется. Мне хочется, чтобы все тесты, требующие БД проходили на одном и том же экземпляре встроенного postgresql.


Создать базовый класс для тестов с одинаковой конфигурацией.

Это ничем не поможет. При необходимости незначительно изменить конфигурацию Spring всё равно будет поднимать БД ещё раз.


Как уже отмечено — иметь одну базу для всех тестов

Это формулировка задачи, а не вариант решения )). Интересно, как это красиво сделать спрингом, если база встроенная.


Подумать над каким-то runtime созданием бинов

Наверное можно, но жутко неохота, хотя подозреваю, что этим и кончится)). Помогла бы какая-нибудь аннотация в Junit наподобие BeforeAll, только чтобы она была BeforeSuite или как-то так, но её по моему нет.

Помогла бы какая-нибудь аннотация в Junit наподобие BeforeAll

Да, ее нет, но например TestContainers выкручиваются используя static поля.

Sign up to leave a comment.

Articles