SpringMvcTest는 End-to-End와 뭐가 다를까?
- `running container`에 의존하지 않음
- `MockHttpServletRequest` 로부터 시작해서 생각했을 때 `no context path` 즉 `no jsessionid cookie, no forwarding, error, or async dispatches`
- 대신 `forwarded`, `redirected` url은 모두 `MockHttpServletResponse` 에 저장됨
- JSP를 사용한다면 JSP가 어디로 forwarded 되는지는 확인 가능하지만 html 이 render 되진 않는다.
- JSON과 @ResponseBody 도 마찬가지로 결과값이 render 되진 않는다.
- 이러한 이유로 @SpringBootTest 를 쓰는 것을 고려하게 되는 것이다.
❗No Context Path 이면 왜 No Jsessionid Cookie 일까?
톰캣 서블릿 컨테이너는 그 안에 여러개의 웹 어플리케이션을 배포할 수 있다. 여러 개의 웹 어플리케이션을 구분하기 위해 context path 라는 것이 주어진다. 이 context path를 통해 서버는 set-cookie를 해주는 것이다.
ex)
Set-Cookie: JSESSIONID=ED92A8FAA8000F9D5B0926ABE51B980A; Path=/; HttpOnly
참고 https://dololak.tistory.com/591
필자는 SpringCloudGateway 에서 필터에 대한 테스트 코드를 쓰는데 실패했다. 실패했던 방법 두가지는 다음과 같다.
- MockServerWebExchange 사용 - exchange 에서 `getSession()` 메소드를 통해 한번 세션이 생성된 유저에 대해서는 인증된 세션을 가져온다는 코드를 쓰고 싶었다. 하지만 간과했던 것은 MockServerWebExchange를 하면 위의 MockServletRequest과 같이 session 이 생성되지 않는다.
- 헤더를 통한 인증된 유저 테스트 - 프로젝트에서 인증된 유저라면 gateway에서 request header 에 userId 를 넣어주었다. 그렇다면 request header 에 제대로 userId가 들어갔는지 확인하면 될거 아닌가 라는 생각에 테스트를 해보았다.
HttpHeaders requestHeaders = testClient.get()
.uri("/brand")
.exchange()
.expectStatus().isOk()
.returnResult(Object.class)
.getRequestHeaders();
log.info("exchangeResponse {}", requestHeaders.entrySet());
Assertions.assertEquals(1, requestHeaders.getFirst("userId"));
확인을 해보니 requestHeader은 gateway에서 mutate 되기 전의 requestHeader가 가져와졌다. mutate된 것을 빼올 방법이 없어보였다.
그렇다면 api 서버에서의 response를 통해 테스트 가능하긴 할거 같았지만 테스트 코드를 쓰기 위해 서버 로직을 바꾸는 것은 비효율적인거 같았다. 그렇게 일단 냅둔 테스트 코드이지만 나중에 공부를 좀더 하고 방법을 찾아보면 좋을거 같다.
'☘️Spring' 카테고리의 다른 글
[Spring] 스프링 시큐리티 기초 정리 (1) | 2024.01.21 |
---|---|
[Spring] JPA N+1 문제 해결 (35) | 2023.10.30 |
[Spring] web mvc 코드로 이해하기 (0) | 2023.09.02 |
[Spring] 의존관계 자동/수동 주입 (0) | 2023.07.09 |
[Spring] 싱글톤 컨테이너 (2) | 2023.07.06 |