이번 포스트에서는 저번 포스트에 이어서 테스트 코드의 용어 설명을 진행하겠다.
1. MockMvc란
- MockMvc는 Spring Test Library에서 제공하는 한 클래스로서, 웹 서버를 따로 구동시키지 않아도 Spring MVC의 동작을 모방(mock)하도록 도와준다. 이를 통해 Controller가 정상적으로 동작하는지 테스트할 수 있다.
1-1. MockMvc 설정하기
- MockMvc 인스턴스는 @WebMvcTest나 MockMvcBuilders를 통해 생성할 수 있다.
@WebMvcTest(controllers = MyController.class)
public class MyControllerTest {
@Autowired
private MockMvc mockMvc;
}
- 위의 코드에서 @WebMvcTest는 Spring MVC에 특화된 슬라이스 테스트를 위한 어노테이션이다.
- controllers 속성으로 테스트할 컨트롤러를 지정한다. MockMvc 인스턴스는 Spring이 자동으로 주입해 준다.
1-2. 요청 보내기
- MockMvc는 perform() 메소드를 통해 HTTP 요청을 보내고 결과를 검증하는 것을 지원한다.
@Test
public void getHello() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hello"));
}
- 응답 검증하기 -> andExpect() 를 사용해서 HTTP 응답을 검증할 수 있다.
- status() : HTTP 상태 코드 검증
- content() : 응답 본문 검증
- header() : HTTP 헤더 검증
- view() : 뷰 이름 검증
- model() : 모델 검증
- jsonPath(), xpath() : JSON 또는 XML 응답 검증
@Test
public void getHello() throws Exception {
mockMvc.perform(post("/person")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\": \"John\", \"age\": \"30\"}"))
.andExpect(status().isOk());
}
- 요청 본문 및 파라미터 검증하기 -> MockMvc는 요청 시 본문(body) 또는 파라미터를 검증하는데 필요한 메소드도 제공한다.
- .param(String name, String... values) : 요청 파라미터 설정
- .content(String content) : 요청 본문 설정
이와 같은 방법으로, MockMvc는 개발자가 웹 애플리케이션의 여러 부분을 유연하게 테스트할 수 있도록 도와준다.
개발자는 실제 웹 서버를 구동하지 않아도 컨트롤러의 로직을 테스트하고, 여러 가지 상황을 모사해볼 수 있다.
이는 빠른 피드백과 효율적인 테스트를 가능하게 한다.
2. MockBean이란 무엇인가?
- "MockBean"은 Spring Framework에서 제공하는 어노테이션이며, 이를 사용하여 테스트 환경에서 mock 객체를 생성하고 관리할 수 있다.
- 이 어노테이션은 Spring Boot에서의 테스트 시 사용되며, 주로 서비스나 리포지토리와 같은 빈(bean)들을 모킹(mocking)하는 데 사용된다.
- @MockBean을 사용하면, 실제 객체 대신 mock 객체를 사용하게 된다. 이렇게 해서 어플리케이션의 다른 부분들이 이 mock 객체와 상호작용하게 하여, 그 상호작용이 올바르게 이루어지는지를 검증하거나, 원하는 동작을 시뮬레이션하는 것이 가능하다.
- 이렇게 하면, 외부 시스템과의 연동, 데이터베이스 작업 등과 같은 복잡하거나 시간이 많이 소요되는 작업들을 간소화하여 테스트를 보다 효율적으로 수행할 수 있다.
예를 들어, 다음과 같이 사용할 수 있다.
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest {
@MockBean
private MyRepository myRepository;
@Autowired
private MyService myService;
@Test
public void testMyServiceMethod() {
// MyRepository의 메소드 호출을 모킹합니다.
Mockito.when(myRepository.someMethod()).thenReturn(someValue);
// 이제 myService.someServiceMethod()를 호출하면,
// 이 메소드 내에서 myRepository.someMethod()가 호출되면 someValue가 반환됩니다.
}
}
2-1. 코드를 보면 왜 service만 @Autowired이고 repository는 @MockBean인가?
이 질문은 테스트 코드 작성 시 가장 기본적인 전략에 관련이 있다.
- 보통 단위 테스트에서는 테스트하고자 하는 특정한 단위(주로 메소드 또는 클래스 단위)의 기능을 확인하기 위해 그 단위를 직접 사용하고(@Autowired), 그 단위가 의존하고 있는 다른 컴포넌트들은 모킹(@MockBean)한다.
- 위의 예시 코드에서 MyService는 테스트하고자 하는 대상이다. 따라서 실제 MyService 인스턴스를 사용하게 된다. 그리고 MyService는 MyRepository에 의존하고 있으므로, MyRepository는 @MockBean을 사용하여 모킹된다.
- 이렇게 함으로써 MyService의 메소드를 테스트할 때 MyRepository의 실제 동작에 의존하지 않고, MyRepository가 어떻게 동작하든 간에 MyService의 동작이 올바른지 확인할 수 있다.
- MyRepository의 실제 동작을 사용하게 되면, 데이터베이스 연결이 필요하거나 네트워크 요청이 필요한 등의 복잡한 설정이 필요하거나, 테스트가 외부 상황에 의해 영향을 받게 될 수 있다.
- 따라서 MyRepository를 모킹하여 이러한 복잡성을 제거하고, MyService의 동작만을 명확하게 테스트할 수 있다.
2023.08.09 - [Spring 테스트코드] - Spring(스프링) - 테스트 코드의 기초(1)
2023.08.09 - [Spring 테스트코드] - Spring(스프링) - 테스트 코드의 기초(3)
반응형
'Spring > 테스트 코드' 카테고리의 다른 글
[스프링, 스프링 부트] Spring test - service 테스트에서 만난 오류 (0) | 2023.08.16 |
---|---|
[스프링, 스프링 부트] Spring test - Mock에 대한 이해 (0) | 2023.08.09 |
[스프링, 스프링부트] Spring test - 테스트 코드의 기초(5) [CRUD 테스트] (0) | 2023.08.09 |
[스프링, 스프링 부트] Spring test - 테스트 코드의 기초(4) [mock 테스트] (0) | 2023.08.09 |
[스프링, 스프링 부트] Spring test - 테스트 코드의 기초(3) [Mockito.when() 메서드] (0) | 2023.08.09 |