
간단한 CRUD 게시판에 대한 테스트를 진행하다가 에러가 떴다.
@WebMvcTest(GuestBoardController.class)
public class ControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
GeustBoardService geustBoardService;
@Test
@DisplayName("MockMVC를 통한 controller 테스트")
void getGuestBoard() throws Exception{
given(geustBoardService.getContent(2L)).willReturn(
new GuestBoardResponseDto(2L,"제목수정","내용수정"));
String BoardId = "2L";
mockMvc.perform(
get("/api/v1/guest/board?id=",BoardId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").exists())
.andExpect(jsonPath("$.title").exists())
.andExpect(jsonPath("$.content").exists())
.andDo(print());
verify(geustBoardService).getContent(2L);
}
}
java.lang.AssertionError: No value at JSON path "$.id"
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:304)
at org.springframework.test.util.JsonPathExpectationsHelper.assertExistsAndReturn(JsonPathExpectationsHelper.java:328)
at org.springframework.test.util.JsonPathExpectationsHelper.exists(JsonPathExpectationsHelper.java:192)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$exists$3(JsonPathResultMatchers.java:123)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)
at com.spring.guestboard.controllertest.ControllerTest.getGuestBoard(ControllerTest.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
...
이런 에러가 떴다. 여기서 주목할 메시지는
"java.lang.AssertionError: No value at JSON path ".id" 즉 .andExpect(jsonPath("$.id").exists())에서 jsonPath에서 존재하는지에 대한 결과에서 $.id 는 존재하지 않아서 였다.
그런데 실제 코드를 실행하면 작동이 잘 되는데 테스트코드에서만 되지 않아 test 코드문제로 인식을 하였다.
코드를 살펴보면,
given ,when, then 단으로 나누어서 보았다.
given(geustBoardService.getContent(123L)).willReturn(...): geustBoardService.getContent(123L) 메서드가 호출될 때 반환할 값을 설정하고, 여기서는 GuestBoardResponseDto 객체를 생성하여 반환한다.
String BoardId = "123";: 테스트할 게시물 ID를 문자열로 정의한다.
mockMvc.perform(...): MockMVC를 사용하여 GET 요청을 수행한다.
/api/v1/guest/board?id=123 경로로 GET 요청을 보내고 응답을 검증한다.
.andExpect(status().isOk()): 응답의 HTTP 상태 코드가 200(OK)인지 확인한다.
.andExpect(jsonPath(".title").exists()), .andExpect(jsonPath("$.content").exists()): JSON 응답에서 각각 id, title, content 필드가 존재하는지 확인한다.
.andDo(print()): 테스트 결과를 출력한다.
verify(geustBoardService).getContent(123L);: 목 객체를 사용하여 getContent(123L) 메서드가 정확히 한 번 호출되었는지 검증한다.
이렇게 코드를 한줄한줄 살펴보다가, 실수를 발견했다.
<변경 전>
get("/api/v1/guest/board?id=", BoardId)):
URL 문자열과 BoardId 변수를 두 부분으로 나눠서 문자열을 연결하는 방식이다.
이 경우, URL 문자열과 BoardId 변수 사이에 ? 문자가 없으므로 잘못된 URL이 된 것이다.
<변경 후>
get("/api/v1/guest/board?id="+BoardId)):
매우 기본적인 자바 문법에 대한 실수였는데 작은 실수인 만큼 바로 찾지 못하였다.이 실수는 곧 나의 실력이라 생각하여 한번 더 꼼꼼히 코드를 작성해야 겠다는 생각이 들었다.