@MockBean
은 스프링부트 3.4.0부터 Deprecated
(코드가 어두워 보이지 않는다면, 우측 하단의 다크모드 버튼을 통해 다크모드를 해제하시면 됩니다!)
기존 테스트 코드들은, 테스트 코드가 스프링 컨테이너의 의존도가 높았다.
이를 개선하고자 Spring Framework 6.2부터 Bean-Override
기능을 테스트 코드에서 활성화한다고 한다.
(물론, Bean-Override
기능은, 프로덕션 코드에서는 지양해야 하고, 어차피 프로덕션에서는 Deprecated 될 기능이다. 즉, Bean-Override 기능이 프로덕션 컨텍스트에서는 없어지고 테스트 컨텍스트에서만 유지되도록 모델이 변경되는 것이다)
기본적이 원리는 Bean-Override
를 통해, Bean
을 테스트용 Bean
으로 교체하는 것이다.
테스트 시작 시 TestContext
가 OverrideProcessor
들을 호출해 기존 BeanDefinition
을 덮어쓰는 정의를 주입한다. @TestBean
을 사용하면 테스트 전용 Bean 재정의 를 자동으로 적용해준다.
@Configuration
class ProdConfig {
@Bean MyService customService() { // 실제 서비스 빈
return new ProdServiceImpl();
}
}
@SpringJUnitConfig
class MyServiceIntegrationTests {
@TestBean // ① 필드 + @TestBean
MyService customService;
static MyService customServiceTestOverride() { // ② 팩터리 메서드
return new SimplifiedServiceImpl(); // ③ 대체 구현: 테스트 컨텍스트에서 등록되는 빈
}
@Test
void verifyOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("customService"))
.isSameAs(customService) // 필드와 동일 인스턴스
.isInstanceOf(SimplifiedServiceImpl.class);
}
}
@MockitoBean과 @MockBean의 차이점
@MockBean
은 스프링 내부 프록시 방식에 의존하고,@MockitoBean
은@BeanOverride
+MockitoBeanOverrideProcessor
를 통해ApplicationContext
에 Mock 객체를 주입해준다.@MockBean
애노테이션은 컴포넌트 내부의 필드 주입에 사용 가능하지만,@MockitoBean
은 불가능하다고 함. (테스트 필드 자체에 주입은 가능하나,@TestConfiguration
클래스에 필드 주입하는데는 사용 불가능)- 정확히는
@MockBean
은 클래스 레벨·필드 레벨 모두 적용 가능하나,@MockitoBean
은 필드 레벨 또는 테스트 클래스 레벨만 지원한다.
- 정확히는
- 따라서
@MockitoBean
은@Configuration
클래스에서 사용 불가능 - 인프라는 테스트 컨텍스트에서만 활성화되어 프로덕션 코드에
@MockBean
이 들어가는 걸 방지할 수 있다고 한다.
@TestConfiguration
public class TestConfiguration {
@MockBean
private OrderService orderService; // 이게 @MockitoBean으로 불가능함
// ...
}
@Import(TestConfiguration.class) // 이런식으로 많이 썼다.
public class OrderController {
@Autowired
private OrderController orderController;
// ...
}
보통 이런식으로 테스트 구성 클래스를 한 곳에 모아두고, @Import
방식으로 설정을 불러왔는데, 이제 이게 불가능해지는 거다.
@WebMvcTest(controllers = {CouponController.class})
// @MockitoBean(types = {PublishCouponService.class}) // 여기에 적어주거나
public class CouponControllerTest {
@Autowired
private CouponController couponController;
@MockitoBean
private PublishCouponService publishCouponService; // 요렇게 하거나
- 클래스 단에 애노테이션과 빈 클래스를 지정해주거나, 필드에 직접 사용해주면 된다.
기존에 이런 스타일로 사용하던 분은 @MockBean
을 @MockitoBean
으로 변경만 해줘도, 대부분의 기능이 그대로 동작할 것이다.
Ref)
https://spring.io/blog/2024/04/16/spring-framework-6-2-0-m1-overriding-beans-in-tests
Spring Framework 6.2.0-M1: Overriding Beans in Tests
Spring Framework 6.2.0-M1 has been released, including changes that resolve more than one hundred issues. Among those are a range of new features in Spring's testing support. In this post, I’d like to walk you through one of these new testing features: B
spring.io
@MockitoBean and @MockitoSpyBean :: Spring Framework
@MockitoBean and @MockitoSpyBean can be used in test classes to override a bean in the test’s ApplicationContext with a Mockito mock or spy, respectively. In the latter case, an early instance of the original bean is captured and wrapped by the spy. The
docs.spring.io
'Spring' 카테고리의 다른 글
[Spring] Spring에서 Bean Validation이 동작하는 내부 원리 (0) | 2025.03.11 |
---|---|
[Spring] JAR로 패키징 vs WAR로 패키징 (0) | 2024.12.24 |