728x90

MockMvc

MockMvc란 실제 객체와 비슷한데 Test를 할때 필요한 기능만 가지는 가짜 객체를 만들어 스프링MVC 동작을 재현할 수 있는 클래스이다.

build.gradle

testCompile('org.springframework.boot:spring-boot-starter-test')

의존성을 추가해준다.

가장 간단한 GET방식을 알아볼 것인데, Http Method의 post, put, patch, delete 들은 어디서 넣으면 테스트 할 수 있는지 별도의 주석으로 첨부하도록 하겠다.

Controller 추가

일단 Controller를 추가해준다.

@RestController
public class MockTestController{

    @GetMapping("/mockTest")
    public String mockTest(@RequestParam String name){
        return name + "님 안녕하세요.";
    }
}

요청 파라미터로 name값을 받아서 안녕하세요를 추가하여 반환해주는 컨트롤러를 작성했다.

Test Code 작성

MockTestController를 테스트하는 클래스를 만들어준다.

@ExtendWith(SpringExtension.class)
@WebMvcTest(MockTestController.class)
public class MockTestControllerTest{
    @Autowired
    private MockMvc mockMvc;

    @Test
    @DisplayName("mockMvc 테스트") //이 DisplayName은 임의로 준 것이기 때문에 안써도 무방하다.
    void 테스트_GET() throws Exception{
        MultiValueMap<String, String> initDatas = new LinkedMultiValueMap<>();

        initDatas.add("name", "홍길동");

        mockMvc.perform(get("/mockTest") // get, post, delete, put, patch를 여기서 매칭시킴
               .params(initDatas))
               .andExpect(status().isOk())
               .andExpect(content().string("홍길동님 안녕하세요"))
               .andDo(print());
    }
}

MockMvc 메소드 정리

  • perform() : 요청을 전송할 때 사용함.
    • 결과 값으로 ResultAction 객체를 받고, 이 객체는 반환값을 검증이나 확인을 하는 andExpect() 메소드 제공 perform(RequestBuilder requestBuilder) - 공식문서 참조
  • get("/mockTest") : Http 메소드를 결정하는 곳(get(), post(), delete(), put(), patch())
    • 괄호 안에는 url 경로를 매칭시킨다.
    • contentType(MediaType type) : json parse
    • content(ObjectMapper) : 요청하는 컨텐츠 contentType으로 변경되어 body에 들어감
  • params(initDatas) : 키,값 파라미터 전달함. 한개일때 param(), 여러개일때 params()
  • andExpect() : 응답을 검증
    • status() : 상태코드를 나타냄. 뒤에 메소드 체이닝으로 ResultMatcher 메소드를 잇는다. 여기선 자주 쓰는것만 정리하겠다.
      • isOk() : HttpStatus 200
      • isCreated() : 201
      • isNotFound() : 404
      • isInternalServerError() : 500
      • is(int status) : HttpStatus 직접 할당
      • view()
        • 뷰 이름 검증
        • view().name("aaa") : 뷰 이름이 aaa인가
      • content() : 응답정보에 대한 검증
        • string() : 괄호안 문자를 포함하는지
  • andDo(print()) : test 응답 결과에 대한 모든 것을 출력한다.

이런식으로 mocking을 하여 테스트를 진행할 수 있다.
이것으로 http method를 다양하게 테스트 해볼 수 있게 되었다.

728x90

'Java' 카테고리의 다른 글

[JPA] 객체 지향 쿼리 심화  (0) 2022.08.05
Effective Java 1장  (0) 2022.08.05
Mock, Mockito  (0) 2022.08.04
[Java] Enum  (0) 2022.08.03
728x90

Mock 빈 오류에 관해서

그동안 혼자 공부한 것들을 토대로 프로젝트를 하나 해보려고 한다.
나름 공부한다고 공부를 했는데 HelloWorld 구현하는데 컨트롤러를 만들어두고 테스트 코드를 내의지대로 처음 작성해봤다.
MockMvc 클래스를 사용하여 Mock Bean을 주입받으려고 했더니 빈이 등록되지 않았다는 오류를 받았다.
일단 오류에는 두가지가 있었다.
@SpringBootTest 어노테이션을 사용할때 @WebMvcTest도 같이 사용해서 MockBean을 주입받는줄 알고 바로 넣었는데 두 Mock객체가 공유되어있는 객체가 아니고 서로 다른 객체이다. 그래서 두개의 빈이 충돌이 발생한다.

여기서 해결책은 두가지였다.

  • @SpringBootTest@AutoConfigurationMockMvc를 사용한 후 MockMvc의 @Autowired를 제거 하는 방법
  • @ExtendWith, @WebMvcTest@Autowired를 같이 사용하는 방법

이렇게 두가지가 있었다.

먼저 @SpringBootTest의 경우 일반적인 테스트로 슬라이싱을 사용하지 않기 때문에 전체 응용 프로그램 Context를 시작한다. 때문에 전체 응용 프로그램을 불러서 모든 bean을 주입하기 때문에 속도가 느리다고 한다.

@WebMvcTest의 경우는 뒤에 ()를 사용해 특정 레이어를 테스트하고 모의 객체를 사용하기 때문에 필요한 bean을 직접 세팅해줘야 하는 단점이 있지만, 가볍고 빠르게 테스트 할 수 있다.

위의 두가지중 아래의 방법에서는 같이 @AutoConfigurationMockMvc를 사용이 가능하다.

가짜 객체인 Mock을 사용할 때 bean 주입하는데에 있어서 이것을 생각하고 주입해주도록 하자.

728x90

'Spring' 카테고리의 다른 글

Spring Data JPA  (0) 2022.08.06
Spring -> Spring Boot 마이그레이션  (0) 2022.08.05
[Spring] Spring Security  (0) 2022.08.03
의존성 주입 어노테이션 정리  (0) 2022.08.03
728x90

Spring Test MockMvc의 한글 깨짐 처리

스프링에서 테스트 코드를 작성할 때 MockMvc를 흔히 사용한다.

대략 아래와 같이 설정하고 사용한다.

변경일자 2022-04-19 수정
MockMvc를 보통 테스트코드를 작성할 때 사용할텐데,

@WebMvcTest를 사용해서 mvc를 위한 테스트를 만들 수 있다.

//@SpringBootTest  
@WebMvcTest(ApiController.class)  
public class ApiControllerTest {  

    private MockMvc mockMvc;  

    @Autowired  
    private WebApplicationContext ctx;  

    @BeforeEach  
    public void setup() {  
        this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx)  
                .alwaysDo(print())  
                .build();  
    }  

    @Test  
    public void aaa() throws Exception {  
        String keyword = "sports";  

        MvcResult result = this.mockMvc  
                .perform(  
                        get("/api/search/" + keyword)  
                )  
                .andExpect(status().isOk());  
    }  
}  

위의 테스트 코드에서는 한글이 없으므로 아무 문제가 없는데, 아래와 같이 한글을 사용하면 깨진 한글이 Controller에 유입될 수 있으며, 결국 원하는 대로 동작하지 않게 된다.

    @Test  
    public void aaa() throws Exception {  
        String keyword = "스포츠";  // 한글 사용  

        MvcResult result = this.mockMvc  
                .perform(get("/api/search/" + keyword))  
                .andExpect(status().isOk());  
    }  

이 문제는 `MockMvc`를 설정할 때 `CharacterEncodingFilter`를 추가해주면 쉽게 해결할 수 있다.

    @Before  
    public void setup() {  
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)  
                .addFilters(new CharacterEncodingFilter("UTF-8", true))  // 필터 추가  
                .alwaysDo(print())  
                .build();  
    }  
728x90

'Spring' 카테고리의 다른 글

Spring -> Spring Boot 마이그레이션  (0) 2022.08.05
[Spring] MockMvc Bean 주입 에러  (0) 2022.08.04
[Spring] Spring Security  (0) 2022.08.03
의존성 주입 어노테이션 정리  (0) 2022.08.03

+ Recent posts