Код-ревью Middle Тестирование в Spring обновлено
Код-ревью: интеграционный тест заказов
Вопрос
Найдите проблемы в тесте.
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@AutoConfigureTestDatabase
class OrderServiceTest {
@Autowired OrderService service;
@Autowired OrderRepository repo;
@MockitoBean MailSender mail;
@Test
void createsOrder() throws Exception {
service.create(new CreateOrder("anna@example.com", 500));
Thread.sleep(3000);
assertEquals(1, repo.count());
}
@Test
void calculatesDiscount() {
assertEquals(450, service.discounted(500, 10));
}
@Test
void sendsMail() {
service.create(new CreateOrder("anna@example.com", 500));
verify(mail).send(any(), any());
}
}
Коротко
Правильно разделить: логику скидок покрыть юнит-тестом без Spring, сохранение заказа проверить @DataJpaTest или @SpringBootTest с Testcontainers и очисткой данных, асинхронные эффекты ждать через Awaitility, а @DirtiesContext убрать.
Что должен найти ревьюер
- Производительностьстрока 1Полный @SpringBootTest для проверки логики сервиса: можно юнит-тестом с моками, а для слоя данных взять @DataJpaTest.
- Производительностьстрока 2@DirtiesContext после каждого метода пересоздаёт весь контекст: тест идёт минуты.
- Ошибкастрока 3@AutoConfigureTestDatabase подменяет базу встроенной H2: native-запросы и особенности PostgreSQL не проверяются. Нужен Testcontainers.
- Ошибкастрока 12Thread.sleep(3000) вместо ожидания условия: тест медленный и всё равно может мигать на медленном CI.
- Ошибкастрока 13Проверка repo.count() == 1 держится только на том, что @DirtiesContext каждый раз даёт пустую базу. Стоит убрать его ради скорости, и тест начнёт зависеть от sendsMail и порядка запуска. Нужна явная очистка данных или проверка конкретного заказа.
- Стильстрока 17Чистая арифметика скидки проверяется с поднятием всего контекста: это юнит-тест.
Разбор
Правильно разделить: логику скидок покрыть юнит-тестом без Spring, сохранение заказа проверить @DataJpaTest или @SpringBootTest с Testcontainers и очисткой данных, асинхронные эффекты ждать через Awaitility, а @DirtiesContext убрать.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.