테스트 코드를 작성하다 보면 redis template을 stub 해야한다. 그런데 redis를 사용하면 문제가 2개가 발생했었는데 우선 redis template을 mocking 해야하고 두번째로는 redis가 데이터를 저장하는 메서드 자체가 void인 경우가 있기 때문이다.
해결 방법은 스택 오버 플로우에 있는 방법으로 해결했다. 근데 5년이 넘은 해결방법이라서 맞을지는 모르겠다.
@MockBean
private RedisTemplate<String, Object> redisTemplate;
@Mock
private ValueOperations valueOperations;
@Test
@DisplayName("session에서 값이 있다면 로그인 성공한다.")
void loginCheckSuccess1() throws Exception {
// given
String accessToken = "access_token";
given(redisTemplate.opsForValue()).willReturn(valueOperations);
doNothing().when(valueOperations).set(anyString(), any());
// when
ResultActions perform = mockMvc.perform(get("/v1/test/login-check").with(request -> {
request.addHeader("TOKEN", accessToken);
request.addHeader("UUID", "uuid");
HttpSession session = request.getSession();
session.setAttribute(accessToken, 123456L);
return request;
}));
perform.andDo(print());
// then
perform.andExpect(status().is2xxSuccessful());
}
내가 작성하던 테스트는 로그인 token을 interceptor에서 확인하는 로직을 테스트하기 위핸 코드였다. 그래서 다음과 같이 RedisTemplate을 MockBean으로 등록하고 ValueOperations를 Mock으로 등록하여 void인 set은 doNothing을 통해 실행하도록 해결하였다.
그런데 막상 이 글을 쓸때 생각해보니 bdd에 빠져버린 결과였다. 통합 테스트 중이였으므로 굳이 redis를 mocking하지 않아도 됐었다... 나처럼 bdd에 빠져서 실제 테스트의 단위를 까먹지 말길...ㅜㅜ 그래도 나중에 단위 테스트를 하거나 redis를 mocking 해야할 때 필요하니까 우선 글로 작성해두려고 한다!