[에러] [Testing] Mockito 사용 중 Misplaced or misused argument matcher detected here: 에러

zini9188·2023년 3월 9일
0

문제해결

목록 보기
3/8

에러 내용

Mockito를 이용하여 테스트를 하는 도중 Misplaced or misused argument matcher detected here: 에러가 발생했다.

원인이라고 생각했던 코드

에러 로그도 여기를 가리키고 있었다.

given(mapper.memberPatchToMember(Mockito.any(MemberDto.Patch.class)))
         .willReturn(new Member());
given(memberService.updateMember(Mockito.any(Member.class)))
         .willReturn(new Member());

해결 과정

크게 두 가지의 원인 로그가 있었는데,
This message may appear after an NullPointerException if the last matcher is returning an object like any() but the stubbed method signature expect a primitive argument, in this case, use primitive alternatives. when(mock.get(any())); // bad use, will raise NPE when(mock.get(anyInt())); // correct usage use

Also, this error might show up because you use argument matchers with methods that cannot be mocked. Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode(). Mocking methods declared on non-public parent classes is not supported.

첫 번째 로그를 보고 "Member.class가 null을 반환할 수 있으니, any가 아닌 anyInt를 사용하라"라는 뜻으로 이해했다.

근데, Member는 클래슨데 Int로 어떻게 사용하라는거지? 라는 생각이 먼저 들었다.

그래서 다른 원인이 있을까 라는 생각으로 아래를 읽어보니, "Mock으로 사용할 수 없는 메서드를 인자 매처로 사용중일 수 있다." 라는 뜻으로 이해되는 로그가 있었다.

그렇게 코드를 살펴보다 도저히 모르겠어 any 사용시 NullPointerError를 검색하기 시작했다. 찾다보니 테스트 객체에는 @InjectMocks를 붙여줘야 한다는 것을 보게 되었고..

그럼 mapper나 service에 문제가 있나? 라는 생각으로 보게된 것이 바로 이것

@MockBean
private MemberService memberService;

@Autowired
private MemberMapper mapper;

mapper는 @Autowired를 사용하여 빈을 주입받고 있었고, mapper @MockBean으로 변경해봤더니 잘 동작하였다.

그래서 뭐가 문제였다는 거지?라는 생각으로 @Autowired@MockBean의 차이점을 찾아봤다.

@Autowired

  • 필요한 의존 객체의 타입을 찾아 해당 빈을 주입

  • 실제 구현된 내용을 사용한다.

@MockBean

  • 껍데기만 있는 객체로 기존에 사용하던 Bean의 껍데기만을 가져와 내부의 구현 부분은 모두 사용자에게 위임한다.

결론

  1. 테스트를 하나 하나 하다보니 patch만 문제인줄 알고 있었지만 사실은 mapper의 빈 주입에 문제가 있어 전체적인 문제였다.

  2. Autowired로 실제 객체를 주입받아야 하는 이유로 mapper에서 가짜 객체를 받는 경우 Null을 가질 수 있음?을 컴파일러가 알려주는 과정에서 오류가 발생했다고 생각한다.

profile
똑같은 짓은 하지 말자

0개의 댓글