[Spring]

조롱이란 무엇입니까?

컨트롤러 테스트를 위해서는 모킹에 익숙해져야 합니다.

조롱하다실제 개체를 사용하여 테스트하는 것처럼 테스트용 모델모조품을 의미합니다.

모의로 테스트하는 과정을 모킹(mocking)이라고 합니다.

웹 애플리케이션 환경에서는 서블릿 컨테이너와 디스패처 서블릿이 메모리에 로드되지만 모킹은 실제 테스트 컨테이너를 사용하므로 별도의 의존성을 가지고 모킹하여 테스트할 수 있다.

SpringBoot 환경에서 테스트 코드를 작성할 때 @SpringBootTest + @AutoConfigureMockMvc 또는 @WebMvcTest 내가 사용할 게. 차이점을 간단히 살펴보겠습니다.

@WebMvcTest 대 @AutoConfigureMockMvc


@WebMvcTest 대 @AutoConfigureMockMvc

@SpringBootTest의 경우 모의 컨테이너 또는 서블릿 컨테이너를 구성할 수 있습니다.

기본값은 모의 서블릿을 사용하며 클래스패스에 WebFlux가 있거나 서블릿 API가 없으면 애플리케이션 컨텍스트가 열린다.

@WebMvcTest와 @AutoConfigureMockMvc를 함께 사용하는 경우 java.lang.IllegalStateException: 구성 오류: 테스트 클래스에 대한 여러 @BootstrapWith 선언을 찾았습니다.

오류 메시지가 나타납니다.


그 이유는 그들이 서로를 조롱하는 동안 충돌이 발생했기 때문입니다.

@WebMvcTest(PostController.class)
public class PostControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private PostService postService;

    @MockBean
    private UserService userService; // 종속성 존재로 MockBean 등록
}
  • @WebMvcTest의 경우 @Service, @Repository 종속성은 제외되므로 테스트에서 사용하지 않더라도 실제로 사용되는 종속 서비스는 다음과 같이 @MockBean으로 등록해야 한다.

    그렇지 않으면 ApplicationContext 오류를 로드할 수 없습니다.

    칠 수 있습니다.

@MockBean 대 @Autowired

@Autowired의 경우 실제 빈을 찾아서 주입그들은 그 목적을 위해 구현된 것을 사용합니다.

@MockBean의 경우 위조된 개체의 가져온 모양Spring Boot Test의 Mockito와 결합하여 실제 로그인한 사용자나 비인가 사용자를 테스트할 수 있습니다.

@MockBean 및 Mockito 사용 @WithMockUser, @WithAnonymousUser, @WithUserDetails 등은 사용자별 인증을 처리할 수 있습니다.

다음과 같이 보안에 사용되는 주석에 대한 정보 B. @WithMockUser, 다음 게시물을 참조하십시오.

컨트롤러 테스트 예시

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
public class PostControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private PostService postService;
    
    @Test
    @WithMockUser
    void 포스트수정() throws Exception{

        String title = "title";
        String body = "body";

        // mocking
        when(postService.modify(eq(title), eq(body), any(), any()))
                .thenReturn(Post.fromEntity(PostEntityFixture.get("userName", 1, 1)));

        mockMvc.perform(put("/api/v1/posts/1")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsBytes(new PostModifyRequest(title, body)))
                ).andDo(print())
                .andExpect(status().isOk());
    }
}
  • @SpringBootTest와 @AutoConfigureMockMvc의 경우 @Service와 @Repository가 모두 메모리에 로드되어 종속 빈에 대한 정보를 가져올 수 있으므로 추가 @MockBean이 필요하지 않습니다.

  • org.mockito 라이브러리를 통해 상황을 가정하여 테스트할 수 있습니다.

    B. 로그인하지 않은 사용자 또는 로그인한 사용자가 게시물을 작성합니다.