특정 계층만 잘라서(Slice) 테스트
스모크 테스트(Smoke Test)
애플리케이션의 특정 수정 사항에 영향받는 범위에 한한 제한된 테스트
@SpringBootTest
Spring Boot 기반 테스트를 위한 ApplicationContext생성을 통한 런타임 환경 구성
MockMvc
Spring MVC 테스트 프레임워크
Tomcat같은 서버 없이 Controller 테스트를 가능하게 함
@AutoConfigureMockMvc 를 사용하여 사용 영역을 설정한다
mockMvc.perform() 메서드로 실행하여 ResultActions객체를 리턴한다
ResultActions 객체로 andExpect() 메서드를 사용하여 검증한다
@SpringBootTest
@AutoConfigureMockMvc와 함께 사용하여
프로젝트에서 사용하는 전체 Bean을 ApplicationContext에 등록하여 사용
편리한 실행 속도가 상대적으로 느리다
DB까지의 통합 테스트에 주로 사용
@WebMvcTest
테스트에 필요한 Bean만 ApplicationContext에 등록하여 사용
Controller에서 의존 객체를@MockBean로 의존성을 제거한 후 사용
번거로우나 상대적으로 빠르다
Controller 슬라이스 테스트에 주로 사용
@SpringBootTest @AutoConfigureMockMvc 설정MockMvc클래스 객체 생성후 빈등록@Test 설정하여 테스트 케이스 작성Given(request body 생성)
Dto객체를 Json객체로 변환
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com", "홍길동", "010-1234-5678")
String content = gson.toJson(Post)
When(핸들러 메서드 실행)
ResultActions actions = mockMvc.perform()
[MockMvc 객체에 포스트 객체를 넣어 실행, ResultActions 객체 리턴]
포스트 객체 설정
post("/v11/members")[request URL 설정]
.accept(MediaType.APPLICATION_JSON)[responseType 설정]
.contentType(MediaType.APPLICATION_JSON)[requestType 설정]
.content(content))[포멧된 requestbody 설정]
Then(핸들러 메서드 리턴값 검증)
핸들러 메서드 리턴값(HTTP Status, response body) 검증(then)
actionsResultActions 객체
.andExpect(status().isCreated())status가 201(Created)가 맞는지
.andExpect(header().string("Location", is(startsWith("/v11/members/"))))
header Location값이 맞는지
@SpringBootTest
@AutoConfigureMockMvc
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private Gson gson;
@Test
void postMemberTest() throws Exception {
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com", "홍길동", "010-1234-5678");
String content = gson.toJson(post);
ResultActions actions = mockMvc.perform(
post("/v11/members")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(content));
actions.andExpect(status().isCreated())
.andExpect(header().string("Location", is(startsWith("/v11/members/"))));
}
}
Given(request body 생성)
앞서 Post된 내용과 해당 location(get요청 임으로 주소값과 파라미터만 있으면 됨)
String location = postActions.andReturn().getResponse().getHeader("Location");
When/Then(핸들러 메서드 실행/리턴값 검증)
mockMvc.perform(get(location).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())200 OK인지를 검증
.andExpect(jsonPath("$.data.email").value(post.getEmail()))
.andExpect(jsonPath("$.data.name").value(post.getName()))
.andExpect(jsonPath("$.data.phone").value(post.getPhone()));
jsonPath().value()로 Json 포멧된 response body의 프로퍼티가 앞전 포스트의 그것과 일치하는지 검증
@Transactional
@SpringBootTest
@AutoConfigureMockMvc
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private Gson gson;
(...)
@Test
void getMemberTest() throws Exception {
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com","홍길동","010-1111-1111");
String postContent = gson.toJson(post);
ResultActions postActions = mockMvc.perform(
post("/v11/members")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(postContent));
//==========================================================================
String location = postActions.andReturn().getResponse().getHeader("Location");
mockMvc.perform(get(location).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.email").value(post.getEmail()))
.andExpect(jsonPath("$.data.name").value(post.getName()))
.andExpect(jsonPath("$.data.phone").value(post.getPhone()));
}
}
JSON 데이터의 한글이 깨질경우, application.yml 설정을 추가
server: servlet: encoding: force-response: true ```