Сколько контекстов Spring Boot создается для двух тестовых классов с аннотацией @SpringBootTest?

Ответ

Поведение зависит от конфигурации тестов и оптимизаций Spring.

  • По умолчанию: Каждый тестовый класс с @SpringBootTest запускает загрузку своего собственного ApplicationContext. Это может быть неэффективно.
  • Кэширование контекста: Spring Test кэширует и переиспользует контексты между тестами, если их конфигурация идентична. Конфигурация определяется параметрами аннотации: classes, properties, webEnvironment и другими атрибутами @SpringBootTest.

Пример:

// Конфигурация идентична -> Spring, скорее всего, создаст и переиспользует ОДИН контекст
@SpringBootTest
class UserServiceTest { /* ... */ }

@SpringBootTest
class OrderServiceTest { /* ... */ }

// Разная конфигурация -> будут созданы ДВА разных контекста
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class WebControllerTest { /* ... */ }

Управление кэшированием: Чтобы гарантированно создать новый контекст для каждого тестового класса (например, для изоляции), используйте аннотацию @DirtiesContext.

@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class IsolatedTest { /* Контекст будет закрыт после этого класса */ }

Ответ 18+ 🔞

Давайте так, блядь. Пять лет я на этой Java, как таракан на кухне — везде свой след оставил, всё попробовал и уже знаю, где вкусно, а где просто красивая обёртка.

Чем конкретно мозги пудрил:

  • Тылы, блядь, серверные: Строил системы, которые не падают, когда на них наваливается овердохуища народу. Не то что эти хлипкие поделки.
  • Мой основной арсенал: Java (от восьмой до семнадцатой, да, я видел, как она росла), весь этот зоопарк Spring — Boot, MVC, Data, Security, Cloud. Hibernate/JPA — чтобы с базой не на уровне пещерного человека общаться.
  • Хранилища всякие: И с этими вашими табличками-связочками (PostgreSQL, MySQL) работал, и с NoSQL (MongoDB, Redis) для скорости, когда надо, как угорелым.
  • Связующее звено: Message brokers (Apache Kafka, RabbitMQ) — чтобы сервисы между собой болтали, REST API, gRPC для особо быстрых перешёптываний.
  • Инфраструктура, ёпта: Заворачивал всё в Docker, потом в Kubernetes пихал, настраивал эти конвейеры CI/CD (GitLab CI, Jenkins), чтобы само всё катилось, как по маслу.

Вот, смотри, как я обычно запросы обрабатываю. Просто, но со вкусом:

@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor // Эта штука от Lombok сама всё нужное в конструктор воткнёт. Красота!
public class UserController {
    private final UserService userService; // Зависимость, блядь. Без неё никуда.

    @GetMapping("/{id}")
    public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
        // Берём и отдаём. Без пафоса, зато работает.
        return ResponseEntity.ok(userService.getUserById(id));
    }
}

А по процессам, блядь: Прошёл всё, от идеи "а давайте сделаем" до момента, когда это уже в продакшене и его мониторишь. Участвовал в планировании, код-ревью проводил (иногда с матом, но по делу), деплоил. Работал по этим вашим Agile/Scrum — иногда эффективно, иногда просто беготня, но привык. Младших товарищей направлял, чтобы под ноги не путались и росли быстрее.