일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 검색
- 서브쿼리
- subquery
- docker명령어
- 네이티브쿼리
- 컨테이너실행
- 2 > /dev/null
- 메세지수정
- foreignkey
- EC2
- ㅔㄴ션
- application.yml
- 추후정리
- Query
- 커밋메세지수정
- 포트
- MySQL
- appspec.yml
- 적용우선순위
- AuthenticationEntryPoint
- 예약
- 메소드명
- WeNews
- appspec
- ubuntu
- 외부키
- 테스트
- 테스트메소드
- querydsl
- 참조키
- Today
- Total
제뉴어리의 모든것
SpringBoot Test에서 현재 등록된 빈 조회하기 (어떤 환경에서든지 가능) 본문
- ApplicationContextProvider
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component //빈으로 등록
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.ctx = ctx;
}
}
- BeanUtils
import org.springframework.context.ApplicationContext;
public class BeanUtils {
static ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
public static Object getBean(String beanId) {
if( applicationContext == null ) {
throw new NullPointerException("Spring의 ApplicationContext초기화 안됨");
}
return applicationContext.getBean(beanId);
}
public static String[] getDefinitionNames() {
return applicationContext.getBeanDefinitionNames();
}
}
- @SpringBootTest 를 사용한 Junit을 이용한 Test환경에서 현재 등록된 빈 조회 코드
@SpringBootTest
@AutoConfigureMockMvc
public class MemberControllerMockTest {
@Test
void beanFind() throws Exception {
String[] definitionNames = BeanUtils.getDefinitionNames();
for (String definitionName : definitionNames) {
Object bean = BeanUtils.getBean(definitionName);
System.out.println(bean);
}
}
}
위에 기능이 필요했던 이유는
@MockBean 애노테이션과 @Autowired 애노테이션을 이용하여 빈을 주입 받았을때,
어떤 차이가 있는지 확인하고 싶었기 때문이다.
그리고 @MockBean 애노테이션에 대해 알아보면서
어떤 블로그에서는 @MockBean을 붙이면 해당 필드의 객체가 스프링 컨테이너에 추가로 등록된다는 글과
또 다른 블로그에서는 앱에서 @Component가 붙어 기존에 등록될 객체를 Mock으로 대체해서 빈으로 등록해준다는 글이 있어서 둘중에 어떤 것이 맞는지 확인하기 위해서이다.
예를들어, MemberService라는 클래스가 앱에서 @Component 애노테이션으로 인해 빈으로 등록되는데
Test에서
MemberService를 @MockBean 으로 의존성 주입받을때,
실제 MemberService 빈, 가짜 MemberService 빈 이렇게 두개가 등록될지
실제 MemberService 빈을 대체하여 가짜 MemberService가 등록될지가 궁금했던것이다.
테스트에 필요한 클래스는 위에 적은 ApplicationContextProvider, BeanUtils 와
아래에 적은 MockBeanTest 클래스 이다.
- Test에 만들어진 클래스 항목 (MemberControllerMockTest 제외한 빨간박스 안에 세개의 클래스이다)
- 테스트 코드
import com.codestates.member.service.MemberService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@SpringBootTest
public class MockBeanTest {
@MockBean
// @Autowired
private MemberService memberService;
@Test
void mockBeanAndAutowiredAnnotationTest() {
/**
* 빈 전체 조회
*/
// String[] definitionNames = BeanUtils.getDefinitionNames();
// for (String definitionName : definitionNames) {
// Object bean = BeanUtils.getBean(definitionName);
// System.out.println(bean);
// }
String[] definitionNames = BeanUtils.getDefinitionNames();
for (String definitionName : definitionNames) {
Object bean = BeanUtils.getBean(definitionName);
if(bean.getClass().getName().contains("MemberService"))
System.out.println(bean);
}
}
}
- 결과 화면
보시다시피
memberService로 등록된 빈은 하나이다.
즉,
@MockBean을 붙여서 필드를 생성하면
해당 클래스의 진짜빈, 가짜빈 두개가 등록되는것이 아니라,
진짜빈을 대체하여 가짜빈 하나만 등록된다.
정말 확식하게 확인하고 싶다면 위에 주석처리한 코드로 전체 빈을 조회해보면 된다.
역시 모든 블로그를 다 믿을 수 없다.
블로그 내용을 가려서 보자.
'Spring Boot' 카테고리의 다른 글
SMTP 를 이용하여 메일 보내기 (0) | 2022.10.18 |
---|---|
Spring Boot 에서 ApplicationEvent 를 사용하여 비동기 처리하기 (0) | 2022.10.18 |
테스트시 사용되는 각종 애노테이션 (0) | 2022.09.13 |
MapStruct 사용법 (1) | 2022.09.11 |
커스텀 애노테이션 만들어서 DTO 유효성 검증하기 (0) | 2022.09.10 |