본문 바로가기
Java

[JAVA/JUnit5/Mokito] given() - 메소드 파라미터가 특정 클래스이면서 특정 필드 값을 가지는 경우 분기하기

2021. 11. 27.
반응형

새로운 팀으로 옮겨진지 약 3달 만에 끔찍한 TF를 벗어나고 드디어 팀에 관련된 일을 하게 되었다. 요즘은 테스트 코드만 하루 종일 짜는 중이다.

자바로 쓰인 Spring Boot 프로젝트에 대한 테스트 코드를 짜고 있어서 JUnit5에 Mokito 라이브러리를 사용 중이다. 테스트 코드를 처음 짜 봐서 초반에 정말 고생했다. 지금도 어려운 건 마찬가지이다.

 

문제점 - given(module.func( (ParamClass)param1)) .willReturn(ret1)을 사용할 때 param1과 다른 인스턴스로 인식되는 case

테스트 코드를 짜 보니 given - when - then 구조로 대부분 구성하게 되었고 given().willReturn() 구문을 자주 이용했다. 그런데 given()에 Mock 객체와 그의 메서드를 넣고, 메서드의 파라미터로 특정 값, 객체, 또는 특정 타입을 지정할 수 있는데, 나는 파라미터가 특정 클래스이면서도 특정 필드 값을 가지는 경우를 조건으로 걸고 싶었다.

그렇다고 파라미터에 객체를 집어넣으면 테스트가 돌아갈 때 실제 코드에서 Mock 객체에 들어가는 객체와 내가 조건으로 걸어준 객체가 (설령 필드 값들이 모두 같을지라도) 주소가 다르기 때문에 다른 값으로 인식되어 내가 원하는 return 값을 뱉어내지 못한다.

 

해결 방안 - 테스트 중 해당 메서드에 입력되는 파라미터 값을 이용해서 결과를 다르게 반환

열심히 구글링을 하다가 아래 글을 발견했다.

 

mockito return value based on property of a parameter

Normally when using mockito I will do something like Mockito.when(myObject.myFunction(myParameter)).thenReturn(myResult); Is it possible to do something along the lines of myParameter.setProperty("

stackoverflow.com

대충 읽어보자면 given() 메서드에 조건 내에서는 이런 케이스에 대해서 분기할 수 있는 방법이 없다고 한다. 그렇지만 willReturn() 대신 willAnswer()를 이용해서 입력된 파라미터의 상태를 확인하여 내가 원하는 대로 결과를 다르게 반환하는 함수를 작성할 수 있었다.

given(module.func(any(ParamClass.class)))
    .willAnswer(invocation -> returnMap.get(invocation.getArgument(0, ParamClass.class).getType()));

2번째 줄에 willAnswer를 통해 받아오는 invocation 인자는 테스트가 수행될 때 module.func()에 입력되는 실제 파라미터 객체를 의미한다.

따라서 invocation.getArgument(0, ParamClass.class)를 통해 첫 번째 파라미터를 ParamClass 형태로 받아올 수 있었다. 그 후 type과 실제 결과 값의 Map인 returnMap을 구현하여 내가 원하는 결과를 반환하도록 설정하였다.

728x90
반응형

댓글