본문 바로가기
Spring

Mockito 테스트 Argument(s) are different 에러

by wwns 2023. 5. 1.
반응형

Mocking을 이용하여 통합 테스트를 진행하다 verify 하는 부분에서 Argument(s) are different 에러가 발생했다.

Argument(s) are different 에러

분명 같은 객체를 사용했는데, 왜 객체 주소값이 다르게 변했는지.. 이해할 수가 없어 Mockito에서 ArgumentMatchers가 어떻게 작동하는 지 알아보았다.

문서에 따르면 다음과 같다

Be reasonable with using complicated argument matching, especially custom argument matchers, as it can make the test less readable. Sometimes it's better to implement equals() for arguments that are passed to mocks (Mockito naturally uses equals() for argument matching). This can make the test cleaner.

Mockito는 인수 일치를 위해 equals()를 사용합니다

문제 상황 이해

테스트 코드

에러 메시지에 의하면 inquiryService에 넘어가는 arguments가 다르다는 것인데, 테스트 코드를 보면 request를 생성하고 이를 전달하고 있다. 코드로만 보고 나는 같은 객체라고 생각했다.

목킹을 이용하고 있으므로

목킹할 때 modify에 넘겨준 아규먼트와 실제로 modify를 호출하면서 넘겨준 아규먼트가 일치하지 않아 발생하는 것.!

이를 이해하고 어떻게 해결하면 좋을 지 여러 방법들을 살펴보았다. 


equals and hashcode 구현

Mockito는 인수 일치를 위해 equals()를 사용합니다

equals와 hashcode 메서드를 구현해놓지 않아 Mockito가 객체의 주소를 비교한 것이고, 이에 따라 Request 클래스에

@EqualsAndHashCode 어노테이션을 활용하여 추가 해주고 테스트해 보았다

테스트가 통과하는 것을 확인할 수 있었다

하지만 EqualsAndHashCode 어노테이션을 추가한 클래스와 추가하지 않은 클래스가 섞여있는 것은 통일성에 어긋난다고 생각하고, 다 어노테이션을 추가하는 것은 아닌 것 같다


Mockito.refEq() 메서드 사용

 

분명 Mocktio에서 제공하는 메서드들이 있을 것이라 생각하고 알아보았더니 문서에서는 다음과 같이 설명하고 있다

객체를 비교할 때 제외할 필드를 설정할 수 있고, 필드별로 값이 일치하는지 비교하는 메서드

마찬가지로 모든 테스트에서 통과하였다


Mockito.any() 메서드 사용

 

any() 메서드를 사용하게 되면 해당 매개변수에 어떤 값이 전달되더라도 검증이 통과하며

이 메서드가 정상적으로 호출되었는지 확인하는데 쓰인다 따라서 통합 테스트보단 단위 테스트에서 정상적으로 호출이 되는지 확인할 때만 사용하는 것이 올바를 수 있다.

매개변수를 검증하지 않기 때문에 어쨌든 모든 테스트가 통과하기는 한다

매개변수에 의존하지 않고 항상 동일한 동작을 수행하는 메서드가 있다면 any()를 사용해도 좋다


결론

 

통합 테스트를 진행하던 중 발생했던 `Argument(s) are different` 에러는 목킹할 때 modify에 넘겨준 아규먼트와 실제로 modify를 호출하면서 넘겨준 아규먼트가 일치하지 않아 발생하는 에러였으며 목킹 방식에 대한 이해가 부족했던 것 같다

 

해결할 수 있는 방법들이 여러 가지 있었지만 Controller를 테스트하는 단계이고, Controller에서 매개변수의 값이 변하는 등의 문제가 발생할 수 있기 때문에 equals를 구현하거나 refEq 메서드를 사용하는 것으로 간추려지며, 통일성을 위해 refEq메서드를 사용해 매개변수를 검증하도록 결정하였다


References

https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/ArgumentMatchers.html#refEq(T,java.lang.String...) 

 

ArgumentMatchers - mockito-core 5.3.1 javadoc

Latest version of org.mockito:mockito-core https://javadoc.io/doc/org.mockito/mockito-core Current version 5.3.1 https://javadoc.io/doc/org.mockito/mockito-core/5.3.1 package-list path (used for javadoc generation -link option) https://javadoc.io/doc/org.m

javadoc.io

https://javadoc.io/static/org.mockito/mockito-core/1.9.0/org/mockito/ArgumentMatcher.html

 

ArgumentMatcher (Mockito API)

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

javadoc.io

https://www.inflearn.com/questions/441973/mock%EC%97%90-stubbing-%EC%A4%91-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%97%90%EB%9F%AC

 

Mock에 Stubbing 중 발생하는 에러 - 인프런 | 질문 & 답변

안녕하세요 백기선님, 강의 재밌게 잘 듣고 있습니다! 강의를 듣고 개인 프로젝트를 공부하는 도중 적용하다가 문제가 발생했는데, 이유를 여쭙고 싶어서 이렇게 질문을 남기게 되었습니다. <테

www.inflearn.com

 

반응형

'Spring' 카테고리의 다른 글

톰캣과 스프링 web 설정  (0) 2023.10.25
카카오 OAuth2.0 적용하기 - 1  (0) 2023.01.09
Spring Security 작동 원리  (0) 2022.11.23
Refresh Token이란?  (1) 2022.11.19
JWT란 무엇인가?  (0) 2022.11.18