class CommentContollerTest {
@Nested
@DisplayName("생성 테스트")
class create {
}
}
@TestMethodOrder(MethodOrder.OrderAnnotation.class)
class CommentContollerTest {
@Order(2)
void test1() {
}
@Order(1)
void test2() {
}
}
test2 -> test1 순서로 실행된다.
class CommentContollerTest {
@RepeatedTest(value = 5, name = " {currentRepetition} / {totalRepetitions} 반복중"
void test1(RepetitionInfo info) {
int 현재_횟수 = info.getCurrentRepetition();
int 전체_횟수 = info.getTotalRepetitions();
}
}
class CommentContollerTest {
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void test1(int num) {
System.out.println(num);
}
}
클래스 위에
@WebMvcTest(controllers = {xxxController.class, yyyController.class})를 붙인다.
@WebMvcTest(controllers = CommentController.class)
class CommentControllerTest {
}
@MockMvc를 주입 받는다.
@Autowired
MockMvc mvc;
주입이 필요한 것을 @MockBean을 통해 가짜 객체를 주입받는다.
@MockBean
CommentService commentService;
given().willReturn() 또는 .willThrow() 를 통해 가짜 서비스에서 반환되는 값을 준다.
given(commentService.createComment(any(), any(), any())).willReturn(responseDto);
mvc.peform(HTTP메소드(url)
.content()
.contentType()
.accept()
.principal())
.andExpect()
.andDo()
이런 식으로 필요한 값을 넣고 예상되는 값을 넣어서 테스트 해준다.
mvc.perform(post("/api/comment")
.content(objectMapper.writeValueAsString(requestDto))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.principal(principal))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.data.content").value("내용"))
.andDo(print());
cotent -> body로 넘겨줄 값
contentType -> 값의 타입 형태
accept -> 전달 받을 타입 형태
principal -> @AuthenticationPrincipal을 통해 받을 값
andExpect -> 예상되는 반환 값
jsonPath -> json형태의 값을 key를 통해 읽는다. 깊이는 .을 통해 들어가는 게 가능
verify().메소드()를 통해 실제로 가짜 객체에서 해당 메소드가 실행됐는지 파악한다.
verify(commentService).createComment(any(), any(), any());
HttpMethod -> MockMvcRequestBuilders 이다. (get(), post() ...)
status(), jsonPath() -> MockMvcResultMatchers 이다.
print() -> MockMvcResultHandlers 이다.
given(), any(), verify() -> BDDMockito 이다.
시큐리티를 통과시켜줄 필터를 만든다.
public class MockSpringSecurityFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
SecurityContextHolder.getContext()
.setAuthentication((Authentication) ((HttpServletRequest) req).getUserPrincipal());
chain.doFilter(req, res);
}
@Override
public void destroy() {
SecurityContextHolder.clearContext();
}
}
WebApplicationContext 를 주입받고 context를 설정해 준다.
@Autowired
WebApplicationContext context;
---------------------------------------------------------------------
@BeforeEach
void setup() {
mvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity(new MockSpringSecurityFilter()))
.build();
}
클래스 위에 @ExtendWith(MockitoExtension.class)를 붙여준다
@ExtendWith(MockitoExtension.class)
class CommentServiceTest {
}
@Mock을 통해 의존성이 필요한 것을 주입받는다.
@Mock
CommentRepository commentRepository;
Controller 테스트와 마찬가지로 given()의 사용이 가능하다.
Assrtions를 활용하자 (나는 assertj를 사용했다)
assertThat().isEqualTo()를 통해 값을 비교할 수 있고
assertThat(responseDto.getContent()).isEqualTo(requestDto.getContent());
assertThatThrownBy().isInstanceOf()를 통해 예외값을 넣을 수 있다.
assertThatThrownBy(() -> commentService.updateComment(commentId, requestDto, user))
.isInstanceOf(NotFoundException.class)
.hasMessage("존재하지 않는 댓글 입니다.");
클래스 위에
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE) 를 붙여준다.
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class CommentRepositoryTest {
}
그 외에는 똑같다. Repository를 주입받고
assertThat() 등을 통해 테스트를 하면 된다.