Controller 클래스의 테스트 코드를 작성하다 보면 컨트롤러 단에서 호출하는 서비스 메서드가 호출할 때 어떤 값이 필요하고 어떤 값을 반환하는지 정도의 검증을 하는 작업도 함께 진행한다.
컨트롤러 메서드는 아래와 같이 존재한다. (ApiResult
클래스는 외부 응답 시 공통적으로 사용하는 클래스이다.)
@RestController
@RequiredArgsConstructor
public class ControllerA {
private final ServiceA serviceA;
@PostMapping("/a")
public ResponseEnity<ApiResult> controllerMethodA () {
serviceA.methodA();
return new ResponseEntity(ApiResult.success());
}
}
클래스 ControllerA
에 대한 테스트 코드는 아래와 같이 적을 수 있다.
컨트롤러에 대한 테스트만을 진행하고자 하여 @WebMvcTest
를 사용하였다.
`@WebMvcTest`는 언제 붙이는가?
@WebMvcTest
는
Only Spring MVC components 에 집중하는 테스트를 수행하는 Class에 붙인다.
그러므로 컨트롤러 클래스에 대한 테스트를 진행할 때 사용할 수 있다.
이 애노테이션을 사용하면 전체 자동 설정 기능을 disable 처리하고, MVC 테스트와 관련된 빈들만 로드한다.
(MVC 테스트와 관련된 빈 : @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans)
즉 @Component, @Service, @Repository 가 붙은 클래스들은 빈으로 등록되지 않는다.
- Spring Security, MockMvc, @AutoConfigureMockMvc는 함께 등록!
- (+) HtmlUnit WebClient, Selenium WebDrive 는 함께 등록!
*만약 전체 애플리케이션 설정 정보를 등록하고 싶다면, @SpringBootTest
를 사용하면 된다.
*JUnit4에서는 @RunWith(SpringRunner.class)
와 함께 사용되어야 한다.
참고 : spring docs
@WebMvcTest(ControllerA.class)
@MockBean(JpaMetamodelMappingContext.class)
class ControllerATest {
@Autowired
MockMvc mockMvc;
@MockBean
ServiceA serviceA;
@Test
@DisplayName("매수 주문 컨트롤러 테스트")
void buyOrder() throws Exception {
mockMvc.perform(
post("/a")
).andExpect(status().isOk())
.andExpect(jsonPath("$.success").exists())
.andExpect(jsonPath("$.time").exists())
.andExpect(jsonPath("$.code").exists())
.andDo(print());
verify(serviceA).methodA();
}
}
행위 검증
ControllerA
클래스의 controllerMethodA()
메서드 내에서 실행되는 serviceA
클래스의 methodA()
메서드에 대해서
어떤 값을 넣었을 때 어떤 값을 반환하는지 확인하는 테스트 코드를 작성할 수 있다.
값을 반환하는 메서드라면, org.mockito.BDDMockito
의 given()
메서드를 사용하여 정상 응답까지 테스트할 수 있다.
given(serviceA.moethodA()).willReturn("1");
값을 반환하지 않는 메서드라면 해당 메서드가 호출되는지를 확인하는 행위 검증이라도 진행하면 좋은데, org.mockito.Mockito
클래스의 verify()
메서드를 이용할 수 있다. 정상적으로 호출되지 않았다면 테스트 코드가 실패한다.
특정 값을 인자로 전달할 때 더 유의미한 테스트일 것으로 보인다.
verify(serviceA).methodA();
'Test Code' 카테고리의 다른 글
[참고 글] Test Double (0) | 2024.05.17 |
---|---|
[JUnit5] @Mock 필드 초기화 시점에 따른 @BeforeAll 이슈 (@BeforeEach, 테스트코드의 라이프 사이클) (1) | 2024.04.07 |
[JUnit5] 실패 케이스 테스트하기 (0) | 2024.02.24 |