본문 바로가기

STUDY/Spring

JUnit5 | Controller 테스트 하기 ( + OAuth2 )

1. TestRestTemplate 이용하기

TestRestTemplate을 이용하기 위해서는 @SpringBootTest어노테이션과 webEnvironment설정이 필요하다.

  • @SpringBootTestwebEnvironment속성 설정을 RANDOM_PORT로 설정
  • @TestConstructor를 명시하여 생성자로 의존관계 주입
  • @ActiveProfiles에 사용할 프로필을 설정 (프로필 설정이 되어있지 않다면 생략)
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@ActiveProfiles(profiles = "local")
public class HelloControllerTest {

    @LocalServerPort
    private int port;

    private final HelloService helloService;

    private final TestRestTemplate restTemplate;

    public ImageControllerTest(HelloService helloService, TestRestTemplate restTemplate) {
        this.helloService = helloService;
        this.restTemplate = restTemplate;
    }

 

그리고 API요청 시 필요한 access token을 발급받는 getAccessToken()메서드를 작성한다.

private String getAccessToken() {  
  String clientId = "foo";  
  String clientSecret = "bar";  
  String username = "id";  
  String password = "password";

  String url = "http://localhost:" + port + "/oauth/token";
  HttpHeaders httpHeaders = new HttpHeaders();
  httpHeaders.setBasicAuth(clientId, clientSecret);

  MultiValueMap body = new LinkedMultiValueMap();
  body.add("username", username);
  body.add("password", password);
  body.add("grant_type", "password");

  HttpEntity httpEntity = new HttpEntity(body,httpHeaders);
  ResponseEntity<HashMap> responseEntity = restTemplate.postForEntity(url, httpEntity, HashMap.class);

  return responseEntity.getBody().get("access_token").toString();

}

 

발급받은 토큰으로 API를 요청하는 테스트 메서드를 작성

@Test  
public void 조회\_테스트() throws Exception {

  HttpHeaders httpHeaders = new HttpHeaders();
  httpHeaders.add("Authorization", "Bearer " + getAccessToken());

  String url = "http://localhost:" + port + "/hello";
  ResponseEntity<HashMap> responseEntity 
          = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(httpHeaders), HashMap.class);

  log.info("responseEntity = " + responseEntity);

  assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);

}  

2. MockMvc 이용하기

MockMvc는 실제 서버를 구동하지 않고 요청 테스트를 할 수 있다.

  • @SpringBootTest는 아무 설정 없이 명시 (기본이 MOCK설정임)
  • @AutoConfigureMockMvc어노테이션을 명시하여 자동으로 MockMvc가 설정되도록 함
  • @ActiveProfiles로 사용할 프로필 명시
@Slf4j
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles(profiles = "local")
public class ImageControllerTest {

    @Autowired
    private MockMvc mvc;

}    

 

access token 발급

private String getAccessToken() throws Exception {
    String clientId = "foo";
    String clientSecret = "bar";
    String username = "id";
    String password = "password";

    ResultActions perform = this.mvc.perform(post("/oauth/token")
                                                .with(httpBasic(clientId, clientSecret))
                                                .param("username", username)
                                                .param("password", password)
                                                .param("grant_type", "password"));

    return (String) new Jackson2JsonParser().parseMap(perform.andReturn().getResponse().getContentAsString()).get("access_token");
}

 

API 요청 메서드 작성

@Test
public void 조회_테스트() throws Exception {
    this.mvc.perform(get("/hello").header(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()))
            .andDo(print())
            .andExpect(status().isOk());
}

 


@BeforeEach를 이용해 access token 초기화

    private String access_token;

    @BeforeEach
    public void getAccessToken() throws Exception {
        String clientId = "";
        String clientSecret = "";
        String username = "";
        String password = "";

        ResultActions perform = this.mvc.perform(post("/oauth/token")
                                                    .with(httpBasic(clientId, clientSecret))
                                                    .param("username", username)
                                                    .param("password", password)
                                                    .param("grant_type", "password"));

        this.access_token = (String) new Jackson2JsonParser().parseMap(perform.andReturn().getResponse().getContentAsString()).get("access_token");
    }