Общая фикстура (General Fixture)

В @BeforeEach создаётся избыточная фикстура «на все случаи жизни». Каждый конкретный тест использует лишь часть созданных объектов, но читатель вынужден разбираться во всей конструкции.

Симптомы

  • @BeforeEach создаёт 5–10 объектов разного типа (admin, manager, product, order, promocode, ...)
  • Конкретный тест-метод использует 1–2 поля из десяти, объявленных в классе
  • Трудно понять, какие поля нужны каждому тесту без чтения всех методов
  • @BeforeEach разрастается по мере добавления новых тестов с разными потребностями
  • Поля класса объявлены «на вырост» — не все используются в существующих тестах

Причины возникновения

  • Попытка вынести «общий» код инициализации, чтобы не повторять его в каждом тесте
  • @BeforeEach добавлялся постепенно без рефакторинга при появлении каждого нового теста
  • Незнание паттернов «Inline Setup» и «Creation Method» как альтернатив
  • Желание следовать DRY даже там, где повторение оправдано для читаемости

Почему это проблема

  • Шум: читая тест, не видно, что важно — нужно смотреть @BeforeEach и тест-метод одновременно
  • Скрытые зависимости: тест молчаливо зависит от порядка инициализации в @BeforeEach
  • Медленная фикстура: создаются объекты, которые ни один тест не использует
  • Трудно добавить новый тест: нужно понять, что уже есть в @BeforeEach, чтобы не конфликтовать

Решение

Минимальная фикстура прямо в тесте (Inline Setup); общее — в именованные helper-методы, а не в @BeforeEach:

// ❌ @BeforeEach создаёт 8 объектов, тест использует 2
@BeforeEach
void setUp() { admin = ...; manager = ...; customer = ...; product1 = ...; ... }

// ✅ только то, что нужно этому тесту
@Test
void applyPromocodeToOrder() {
    Order order      = orderFactory.create(userFactory.createCustomer(), productFactory.create());
    Promocode promo  = promocodeFactory.create("SALE10", 10);
    orderService.applyPromocode(order, promo);
    assertThat(order.getDiscount()).isEqualTo(10);
}