레벨2에선 이제 스프링을 사용하기 시작했다.
멋들어지게 스프링을 사용하고 요구 사항을 만족하여 테스트를 돌려봐도 다 잘 돌아갔다.
하지만 애플리케이션을 띄우고 테스트를 실행하면 에러가 발생했다.
왜일까 문제 해결을 위해 고민해보자.
🙋♂️: 애플리케이션을 띄우지 않고는 테스트가 성공했으니, 테스트를 돌릴 때마다 애플리케이션을 종료하고 테스트를 돌리면 되지 않나요?
👨💻: 애플리케이션을 종료하면 안되는 상황이거나 애플리케이션을 재가동 시킬 때 많은 시간이 소모된다면?
🙋♂️: 흠... 어쩔 수 없네요. 다른 방법을 찾아보죠.
에러 로그를 쭈욱 내려다보면
org.springframework.boot.web.server.PortInUseException 이라고 다시 말해 포트는 이미 사용중이라고 친절하게 설명해주고 있다.
애플리케이션을 띄울 때 스프링은 디폴트로 8080 포트를 사용한다. 테스트를 실행할 때도 역시 디폴트인 8080 포트를 사용하려고 하여 예외가 발생하는 것이다.
💁♂️: 아하 그럼 @SpringBootTest 애노테이션의 webEnvironment 속성을 사용하여 port를 변경해주면 되겠군요!
webEnvironment이 DEFINED_PORT로 되어 있으니 src/test/resources/application.properties에서 port를 정의해줄일만 남았다.
포트를 정의하고 테스트하니 성공하였다!
본김에 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] 스프링 빈 프로퍼티 애노테이션 @Profile, @Order (4) | 2024.11.14 |
---|---|
[Spring] 금쪽이 Server-Sent-Event (SSE) (0) | 2024.10.07 |
[Spring] 우리집을 못 찾겠군요 (feat: @RestControllerAdvice, @Order) (1) | 2024.08.18 |
[Spring] 액추에이터 Actuator (0) | 2024.08.05 |
[Spring] @ResponseBody vs ResponseEntity (0) | 2024.04.21 |