본문 바로가기

Study/개발일지

[백엔드온라인TIL] Spring MockMVC 테스트 방법(51일차)

1. @SpringBootTest와 @AutoConfigureMockMvc

스프링부트에서는 Test 클래스를 만들면 @SpringBootTest 어노테이션만 붙어 있습니다.

MockMvc로 테스트를 하기 위해서는 @AutoConfigureMockMvc를 추가적으로 붙여야 합니다.

주의할 점은 Test 클래스에서는 MockMvc를 스프링 컨테이너로부터 주입받을 때 생성자, Setter 방식으로 주입이 불가능합니다. 따라서 필드에 @Autowired를 붙여서 사용해야만 합니다.

 

2. @WebMvcTest

 

웹 환경의 테스트를 경량화해서 진행할 수 있는 어노테이션입니다.

 

@WebMvcTest 아래처럼 적용할 컨트롤러 클래스를 명시해줘야 동작합니다.

 

 

  @WebMvcTest(UserController.class)

 

 

 

사용방법

Junit4를 사용하기 위해 의존성에 spring-boot-starter-test를 추가해줍니다.

 

build.gradle

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

 

 

1. Controller 추가

가장 먼저 컨트롤러를 추가해줍니다.

BlogController.java

@RestController
public class BlogController {

  @GetMapping("/blog")
  public String blogGet(@RequestParam String name, @RequestParam String id){
    return name + "의 블로그입니다. " + id;
  }
}

@RequestParam을 사용해서 name과 id를 받고, 그대로 리턴해주는 컨트롤러를 작성했습니다.

 

2. Test 추가

방금 작성한 컨트롤러에 대한 테스트를 추가해줍니다.

intelliJ의 경우에는 컨트롤러 이름 끝에서 Alt + Enter를 누르면 간편하게 추가할 수 있습니다. 저는 Junit4를 사용하기 때문에 Testing library를 Junit4로 지정해주었습니다.

 

BlogControllerTest.java

@SpringBootTest
@AutoConfigureMockMvc
class BlogControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @Test
  public void test_get() throws Exception {
    MultiValueMap<String, String> info = new LinkedMultiValueMap<>();

    info.add("name", "칩");
    info.add("id", "chip");
    mockMvc.perform(get("/blog")
        .params(info))
        .andExpect(status().isOk())
        .andExpect(content().string("칩의 블로그입니다. chip"))
        .andDo(print());

  }
}

위와 같이 코드를 작성해줍니다.

🐬 mockMvc의 메소드 

1) perform()

  • 요청을 전송하는 역할을 합니다. 결과로 ResultActions 객체를 받으며, ResultActions 객체는 리턴 값을 검증하고 확인할 수 있는 andExcpect() 메소드를 제공해줍니다.

 

2) get("/mock/blog")

  • HTTP 메소드를 결정할 수 있습니다. ( get(), post(), put(), delete() )
  • 인자로는 경로를 보내줍니다.

 

3) params(info)

  • 키=값의 파라미터를 전달할 수 있습니다.
  • 여러 개일 때는 params()를, 하나일 때에는 param()을 사용합니다.

 

4) andExpect()

  • 응답을 검증하는 역할을 합니다.
  • 상태 코드 ( status() )
    • 메소드 이름 : 상태코드
    • isOk() : 200
    • isNotFound() : 404
    • isMethodNotAllowed() : 405
    • isInternalServerError() : 500
    • is(int status) : status 상태 코드
  • 뷰 ( view() )
    • 리턴하는 뷰 이름을 검증합니다.
    • ex. view().name("blog") : 리턴하는 뷰 이름이 blog인가?
  • 리다이렉트 ( redirect() )
    • 리다이렉트 응답을 검증합니다.
    • ex. redirectUrl("/blog") : '/blog'로 리다이렉트 되었는가?
  • 모델 정보 ( model() )
    • 컨트롤러에서 저장한 모델들의 정보 검증
  • 응답 정보 검증 ( content() )
    • 응답에 대한 정보를 검증해줍니다.

 

5) andDo(print())

  • 요청/응답 전체 메세지를 확인할 수 있습니다.

 

3. 결과 확인

테스트를 실행하면 성공한 화면과 Request / Response 전체 메세지를 확인할 수 있습니다.


📩 POST 방식으로 사용하는 방법

이번에는 POST 방식으로 요청을 보내는 경우, 테스트를 하는 방법에 대해 알아보도록 하겠습니다.

 

1. VO 추가

Info.java

public class Info {

  private String name;
  private String id;

  public Info(String name, String id) {
    this.name = name;
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public String getId() {
    return id;
  }
}

값을 받을 VO를 만들어줍니다.

 

2. Controller 추가

BlogController.java

@RestController
@RequestMapping("/mock")
public class BlogController {

  // ...

  @PostMapping("/blog")
  public String blogPost(@RequestBody Info info){
    return info.getName() + "의 블로그입니다. " + info.getId();
  }
    
}

POST로 받는 컨트롤러 메소드를 추가해줍니다.

JSON으로 값을 보낼 것이기 때문에, @RequestBody를 이용해서 객체를 받아준 후에 값을 리턴해줍니다.

 

3. Test 추가

BlogControllerTest.java

@SpringBootTest
@AutoConfigureMockMvc
public class BlogControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private ObjectMapper objectMapper;

  // ...

  @Test
  public void test_POST() throws Exception {

    String content = objectMapper.writeValueAsString(new Info("데일", "dale"));

    mockMvc.perform(post("/blog")
            .content(content)
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk())
        .andExpect(content().string("데일의 블로그입니다. dale"))
        .andDo(print());
  }
}

이번에도 위와 같이 코드를 작성해줍니다. 각 메소드가 무슨 역할을 하는지는 아까 다뤘기 때문에 다시 다루지 않았습니다.

 

4. 결과 확인

이번에도 정상적으로 테스트를 통과하는 것을 확인할 수 있습니다!

 

한글깨질때

 

@Autowired
private WebApplicationContext ctx;

@BeforeEach
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(ctx)
.addFilters(new CharacterEncodingFilter("UTF-8", true))
.build();

}

테스트 클래스에 해당내용 추가 

 

728x90