테스트코드 복습해 보기

GyungKu·2023년 12월 4일
0

JUnit의 어노테이션

@Nested

  • 테스트를 그룹 지어줄 수 있다. class위에 붙인다. (내부 클래스 만들어서)
class CommentContollerTest {
	@Nested
    @DisplayName("생성 테스트")
    class create {
    }
}

@DisplayName("테스트 이름")

  • 테스트 이름을 지정해 줄 수 있다.
  • 메소드위, 클래스위 모두 지정해 줄 수 있다.

@Order(숫자)

  • 테스트의 순서를 정해줄 수 있다.
  • 사용할 때는 클래스 위에 @TestMethodOrder(MethodOrder.OrderAnnotation.class) 를 붙여야 한다.
@TestMethodOrder(MethodOrder.OrderAnnotation.class)
class CommentContollerTest {
	@Order(2)
    void test1() {
    }
    
    @Order(1)
    void test2() {
    }
}

test2 -> test1 순서로 실행된다.

반복

@RepeatedTest(value = 반복 횟수, name = "반복테스트 이름")

  • 이름에는 {currentRepetition}, {totalRepetitions} 를 통해 현재 횟수, 전체 횟수를 이름에 넣을 수 있다.
  • 파라미터로 RepetitionInfo를 받아서 메소드 안에서 반복 횟수를 사용할 수 있다.
class CommentContollerTest {
	@RepeatedTest(value = 5, name = " {currentRepetition} / {totalRepetitions} 반복중"
    void test1(RepetitionInfo info) {
    	int 현재_횟수 = info.getCurrentRepetition();
        int 전체_횟수 = info.getTotalRepetitions();
    }
}

@ParameterizedTest & @ValueSource(타입 = {값1, 값2})

  • 전달하고 싶은 파라미터를 넣을 수 있다.
  • 넣은 값 만큼 순서대로 반복한다. (향상된 for문과 비슷하다.)
class CommentContollerTest {
	@ParameterizedTest
	@ValueSource(ints = {1, 2, 3, 4, 5})
    void test1(int num) {
    	System.out.println(num);
    }
}

단위 테스트

Controller 테스트

클래스 위에
@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());

각각 import

HttpMethod -> MockMvcRequestBuilders 이다. (get(), post() ...)
status(), jsonPath() -> MockMvcResultMatchers 이다.
print() -> MockMvcResultHandlers 이다.
given(), any(), verify() -> BDDMockito 이다.

Controller에서 Securiy 설정이 있을 때

시큐리티를 통과시켜줄 필터를 만든다.

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();
    }

Service 테스트

클래스 위에 @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("존재하지 않는 댓글 입니다.");

Repository 테스트

클래스 위에
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
를 붙여준다.

@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class CommentRepositoryTest {
}

그 외에는 똑같다. Repository를 주입받고
assertThat() 등을 통해 테스트를 하면 된다.

0개의 댓글