본문 바로가기
카테고리 없음

[JUnit] @SpringBootTest, @WebMvcTest, @MockBean, WebClinet

by 비타민찌 2022. 9. 16.
728x90

다음과 같은 컨트롤러와 서비스가 있다.


SampleController.java

@RestController
public class SampleController {

    private SampleService sampleService;

    public SampleController(SampleService sampleService) {
        this.sampleService = sampleService;
    }

    @GetMapping("/hello")
    public String hello() {
        return "hello " + sampleService.getName();
    }
}

 

SampleService.java

  @Service
  public class SampleService {
      public String getName() {
          return "vitamin";
      }
  }

* localhost:8080/hello로 요청을 보내면 'hello vitamin'을 응답값으로 준다.

 

 

MockMvc를 이용한 테스트

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)

디폴트값이다. 괄호 안에 옵션안주면 자동적용된다. 내장 톰캣을 실행시키지 않고, MockMvc 빈으로 등록 시키지 않는다.

따라서 MockMvc를 이용하기 위해서는 @AutoConfigureMockMvc가 필요하다.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
class SampleControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
void hello() throws Exception {
    mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
            .andExpect(status().isOk())
            .andExpect(content().string("hello gracelove"))
            .andDo(print());
	}
}

 

TestRestTemplate 을 이용한 테스트

RANDOM_PORT옵션주면 내장 톰캣을 실행한다.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SampleControllerTest2 {

@Autowired
TestRestTemplate testRestTemplate;

@Test
void hello() {

    String result = testRestTemplate.getForObject("/hello", String.class);
    assertThat(result).isEqualTo("hello gracelove");
	}
}

 

WebTestClient를 이용한 테스트

non-blocking 기반의 클라이언트다. 이용하기 위해서는 pom.xml 에서 다음과 같이 의존성을 추가해줘야 한다.

 <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SampleControllerTest3 {

    @Autowired
    WebTestClient webTestClient;

    @Test
    void hello() {
        webTestClient.get().uri("/hello").exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("hello vitamin");
    }
}

 

@WebMvcTest와 @MockBean을 이용한 테스트

위 테스트코드들은 모두 통합테스트다. 기본적으로 @SpringBootTest 어노테이션을 사용하면 스프링이 관리하는 모든 빈을 등록시켜서 테스트하기 때문에 무겁다. 하지만 @WebMvcTest는 web 레이어 관련 빈들만 등록하므로 비교적 가볍다. web 레이어 관련 빈들만 등록되므로 Service는 등록되지않는다. 따라서 가짜(mock객체)로 만들어줄 필요가 있다. (@MockBean)

@WebMvcTest(SampleController.class)
class SampleControllerTest4 {

 @Autowired
 MockMvc mockMvc;

 @MockBean
 SampleService mockSampleService;

 @Test
 void hello() throws Exception {
     when(mockSampleService.getName()).thenReturn("vitamin");

     mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
             .andDo(print())
             .andExpect(status().isOk())
             .andExpect(content().string("hello vitamin"));
	}
}
728x90

댓글