We will find a way, we always have.

-interstellar

Spring

[Spring] 애플리케이션과 테스트 동시에 실행하기(RestAssured 포트설정)

Redddy 2024. 5. 4. 23:44

레벨2에선 이제 스프링을 사용하기 시작했다.

멋들어지게 스프링을 사용하고 요구 사항을 만족하여 테스트를 돌려봐도 다 잘 돌아갔다.

 

하지만 애플리케이션을 띄우고 테스트를 실행하면 에러가 발생했다.

 

 

 

왜일까 문제 해결을 위해 고민해보자.

 

 

🙋‍♂️: 애플리케이션을 띄우지 않고는 테스트가 성공했으니, 테스트를 돌릴 때마다 애플리케이션을 종료하고 테스트를 돌리면 되지 않나요?

 

👨‍💻: 애플리케이션을 종료하면 안되는 상황이거나 애플리케이션을 재가동 시킬 때 많은 시간이 소모된다면?

 

🙋‍♂️: 흠... 어쩔 수 없네요. 다른 방법을 찾아보죠.

 

에러 로그를 쭈욱 내려다보면 

 

 

 

org.springframework.boot.web.server.PortInUseException 이라고 다시 말해 포트는 이미 사용중이라고 친절하게 설명해주고 있다.

 

애플리케이션을 띄울 때 스프링은 디폴트로 8080 포트를 사용한다. 테스트를 실행할 때도 역시 디폴트인 8080 포트를 사용하려고 하여 예외가 발생하는 것이다.

 

💁‍♂️: 아하 그럼 @SpringBootTest 애노테이션의 webEnvironment 속성을 사용하여 port를 변경해주면 되겠군요!

 

webEnvironment이 DEFINED_PORT로 되어 있으니 src/test/resources/application.properties에서 port를 정의해줄일만 남았다.

 

 

like this

 

tada

 

포트를 정의하고 테스트하니 성공하였다!

 

본김에 webEnvironment의 속성을 좀 더 알아보자.

 

  • MOCK
    MOCK은 디폴트값이다. 이 녀석은 웹 ApplicationContext를 로딩하고, 웹 환경이 애플리케이션의 클래스 경로에 있는 경우 내장 서버를 시작하는 대신 mock 웹 환경을 활용한다. 아니라면 웹 기능이 없는 일반 ApplicationContext를 로딩한다.

  • RANDOM_PORT
    웹 ApplicationContext를 로딩하고 내장 서버를 시작해서 사용 가능한 임의의 포트에 노출된 실제 웹 환경을 제공한다. 이때 포트를 랜덤으로 설정해준다.

  • DEFINED_PORT
    RANDOM_PORT와 거의 동일하고 포트만 사용자가 정의한 포트로 열린다는 점만 다르다. application.properties에서 정의 가능하고 server.port=0 으로 설정해도 랜덤으로도 가능하다.

  • NONE
    모의 웹 환경이나 실제 웹 환경이 전혀 없는 ApplicationContext가 생성된다. 내장 서버도 시작되지 않는다.

 

RANDOM_PORT로 했을 때 8080이 될 확률이 있지 않을까 궁금했다. 구글링을 하며 찾아다녔지만 찾을 순 없었고 몇번 테스트해본 결과 랜덤으로 웰노운 포트와 등록된 포트가 할당되진 않고 동적 포트로만 할당되는 듯 하다.

 

  • 0번 ~ 1023번: 잘 알려진 포트 (well-known port)
  • 1024번 ~ 49151번: 등록된 포트 (registered port)
  • 49152번 ~ 65535번: 동적 포트 (dynamic port)

 

이렇게 서버를 띄우고도 테스트 코드를 잘 동작시킬 수 있었다.🤸‍♂️

 

 

 

이제 LMS 테스트를 실행해보자.

어라 처음보는 RestAssered 가 있다. 어라? 요녀석은 테스트가 실패한다.

 

 

 

연결이 거절됐다는 에러가 떴다. 왜인지 이번에도 포트 문제일 거 같다. 

 

RestAssered 라이브러리를 들어가보니 포트를 8080으로 사용하고 있었다.

 

타다

 

우리는 @LocalServerlPort 애노테이션을 활용해서 런타임시 할당된 HTTP 서버 포트를 가져올 수 있다.

 

 

 

스프링이 우리가 지정한 포트로 문을 열어주었지만 RestAssured는 무시하고 자기가 지정한 포트를 사용하고 있었기 때문에 거부당한 것이다. 

 

RestAssured의 포트와 스프링 서버의 포트를 동일하게 변경해주면 문제 해결이닷.

 

 

@LocalServerPort 애노테이션을 활용해 할당된 포트를 가져오고 매 테스트 전에 RestAssured의 포트를 가져온 포트로 주입시켜준다.

 

 


 

나는 테스트에서 @DirtiesContext 애노테이션을 사용하였기에 테스트 실행시간이 매우 오래 걸렸다. 

(@DirtiesContext 요 친구가 매 테스트마다 컨텍스트를 다시 로드하기 때문)

 

 

어떻게 하면 테스트하고자 하는 메서드만 테스트할 수 있고, 다른 메서드의 의존해 검증하지 않으며, 빠르고 신속하며, 시간이 지나도 깨지지 않는 테스트를 짜는 방법을 고민하고 있다. 

 

 

 

웃자

 

'Spring' 카테고리의 다른 글

[Spring] @ResponseBody vs ResponseEntity  (0) 2024.04.21