MockMvc로 테스트를 하다가 @Mock과 @MockBean의 차이가 뭔지 궁금해졌다. 비슷하게 생긴 두 어노테이션은 엄연히 용도가 다르다. 간단하게 정리해보자.
@Mock
어노테이션 단어 그대로 Mock 객체, 즉 가짜 객체로 쓰겠다는 뜻이다.
@ExtendWith(MockitoExtension.class)
class ServiceTest {
private Service service;
@Mock
private Repository Repository;
@BeforeEach
void setUp() {
service = new Service(repository);
}
@Test
void findAll() {
given(repository.findAll()).willReturn(...);
List<String> actual = service.findAll();
...
}
가짜 repository로 Serivce객체를 생성해서 협력 객체인 repository의 값을 지정해줘서 service 로직만을 테스트했다. 단순히 가짜 객체를 만들어서 값을 지정해주고 싶다면 @Mock 어노테이션을 쓰면 된다.
@MockBean
MockBean 또한 어노테이션 단어 뜻 그대로 Mock Bean, 즉 가짜 Bean을 만들겠다는 뜻이다.
@WebMvcTest(controllers = Controller.class)
@AutoConfigureMockMvc
class ContollerTest {
private MockMvc mockMvc;
@MockBean
private Service service;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(new CharacterEncodingFilter("UTF-8", true))
.build();
}
@Test
void findAll() {
given(service.findAll()).willReturn(...);
mockMvc.perform(get("/")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()))
...
}
}
실제 요청을 하고 Service에는 지정된 값을 줘서 Controller 로직을 테스트했다.
@WebMvcTest 이기 때문에 Controller까지는 로드 된다. 하지만 Controller의 협력 객체인 Service는 로드되지 않는다.
그래서 contoller에 실제로 요청을 보낼 때 controller의 협력 객체인 service가 Bean Container에 생성되어 있지 않다면 NPE가 터진다.
이 처럼 @MockBean은 Bean Container에 생성돼야만 하는 가짜 객체일 때 사용하면 된다.
'Spring' 카테고리의 다른 글
DDD에서는 왜 간접 참조를 더 권장할까? (0) | 2020.10.10 |
---|---|
WebMvcConfigurer addResourceHandlers 경로 설정 (0) | 2020.09.12 |
MockMvc VS RestAssured (0) | 2020.08.14 |
Tacademy JPA 강의 정리 (1) | 2020.07.01 |
용어 정리 (0) | 2020.04.21 |