Spring : java.lang.AssertionError: No value at JSON path

상우·2024년 12월 22일

상황

controller에 대한 테스트코드를 작성중이었다.

AddressController

@RestController
@RequiredArgsConstructor
@RequestMapping("/task")
public class AddressController {

    private final AddressService addressService;

    @PostMapping("/addresses")
    public ResponseEntity<AddMemberAddressResponse> addMemberAddress(@RequestHeader("X-MEMBER-ID") Long memberId ,
                                                                     @RequestBody AddMemberAddressRequest request){

        AddMemberAddressResponse resp = addressService.addMemberAddress(memberId, request);
        return new ResponseEntity<>(resp,HttpStatus.OK);
    }

AddressControllerTest

문제

그런데 테스트를 실행하자 아래와 같은 에러가 발생했다. 왜지?

json path에 "$.name" 이란 값이 없다고 뜨고
왜그런가 확인해보니
response의 body가 비어있는걸 볼 수 있었다.

원인

참조한 블로그 : https://velog.io/@wool_ly/SpringTest-MockHttpServletResponse-body%EA%B0%80-empty-null%EC%9D%BC-%EB%95%8C

원인이 되는 부분은 이 부분이었다

내가 원래 예상했던 결과

테스트 코드에서
이렇게 addressService.addMemberAddress 를 스터빙을 했으니

테스트코드를 실행한다면
컨트롤러에 이렇게 들어가고

서비스에 이렇게 들어가서

내가 스터빙해놓은대로
반환하라고 한 addMemberAddressResponse가 반환되겠지?

실제로 발생한 결과

테스트 코드에서
이렇게 addressService.addMemberAddress 를 스터빙을 해놓았으나

정작 테스트를 위해 mockMvc로 요청을 만들어 보낸다면
addMemberAddressRequest@1이 들어가는게 아니라

  • addMemberAddressRequest@1의 value를 String으로
  • String을 다시 json형태의 content로

만들어 요청을 보내게 되고
이러한 요청을 받은 Controller는
json 메시지를 역직렬화하여 새로운 AddMemberAddressRequest를 만들게된다
(addMemberAddressRequest@2)

파라미터로 addMemberAddressRequest@2가 들어갔을 경우에 대한
addressService.addMemberAddress 메서드는 스터빙이 되어있지 않으므로
따로 리턴될게 없다
그래서 body가 비어있었던 것이다

  1. addMemberAddressRequest@1 -> String -> json 변경되어
  1. json -> addMemberAddressRequest@2가 컨트롤러의 파라미터에 들어가고
  1. 서비스에 이렇게 들어가는데
  1. 테스트코드에서 파라미터로 addMemberRequest@2가 들어온 경우에 대해서는 스터빙한게 없기때문에, 반환값 없음...

해결

두가지로 해결이 되었다

1. when에서 any사용

따라서 어떤 매개변수가 들어가든, 항상 동일한 결과를 돌려줄 수 있도록
Mockito에서 지원하는 any() 메서드를 사용하여 스터빙 한다면
문제가 해결되었다

2. Request에 equalsAndHashcode

아니면 두번째로는 테스트코드는 그대로 두고
AddAddressMemberRequest 클래스에 @EqualsAndHashCode 어노테이션을 붙이는것이었다.

이렇게 되면 새로운 AddMemberAddressRequest 객체가 만들어진다 하더라도
같은 값이라면 같은 동일한 객체로 보기 때문에
문제없이 테스트코드가 작동하였다.

profile
엉성해도 우직하게

0개의 댓글