Mockito when-thenReturn 사용 시 WrongTypeOfReturnValue 오류

2023. 5. 10. 14:10Spring

728x90

Junit 5와 Mockito를 사용해서 테스트 코드를 작성하던 중...

 

@DisplayName("login시 loginTokenDto가 반환되는 지 확인")
@Test
void login_return_loginTokenDto(){
    when(memberRepository.findById(loginRequest.getMemberId())).thenReturn(Optional.ofNullable(member));
    when(authService.generateToken(loginRequest.getMemberId())).thenReturn(loginTokenDto);
    Assertions.assertThat(authService.login(loginRequest)).isEqualTo(loginTokenDto);
}



아래와 같은 오류를 만났다.

 

LoginTokenDto cannot be returned by createRefreshToken()
createRefreshToken() should return String
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

 


오류 메시지를 확인해보면, createRefreshToken()의 메서드는 LoginTokenDto를 반환할 수 없다고 되어있다.

하지만, 테스트코드에서는 Mock을 사용해 generateToken() 메서드의 반환값을 loginTokenDto로 지정하고 있다.



물론, generateToken()안에 createRefreshToken() 메서드가 있긴 하지만,

Mock을 사용해 스터빙한 메소드 호출 후 어떤 객체를 리턴할 지 정의하였기 때문에 문제가 되지 않는다고 생각했다.



따라서, 구글링 하던 와중에 Mock에서 스터빙을 하는 데에는 2가지 방법이 있다는 것을 알았고 이것이 오류를 해결하는 데에 있어 실마리가 되었다.



스터빙을 하는 방법은 2가지가 있다.

 

1. OngoingStubbing

2.Stubber



OngoingStubbing 메소드란 when에 넣은 메소드의 리턴 값을 정의해주는 메소드이고, Stubber 메소드는 OngoingStubbing과는 다르게 when에 스터빙할 클래스를 넣고, 그 후에 메소드를 호출합니다.

 

이 두 방법의 주요한 차이는 스터빙이 반드시 실행되야 하는 것에대한 유무이다. -> Stubber

 

authService의 login() 메서드를 실행하려면, findById() 메서드와 generateToken() 메서드가 반드시 실행이 되어야한다.

 

따라서, 아래와 같은 방법으로 테스트 코드가 작성하면 오류가 나지 않고 성공적으로 테스트가 마무리 되는 것을 확인할 수 있다.


 

@Test
void login_return_loginTokenDto(){
    doReturn(Optional.of(member)).when(memberRepository).findById(loginRequest.getMemberId());
    doReturn(loginTokenDto).when(authService).generateToken(loginRequest.getMemberId());
    Assertions.assertThat(authService.login(loginRequest)).isEqualTo(loginTokenDto);
}

 


솔직히, 이것이 오류의 원인인 지는 확신하지 못 하겠으나 필자는 가능성이 높다고 판단했다.

 

혹시 원인을 아신다면, 댓글 달아주시면 감사하겠습니다!!

 

728x90

'Spring' 카테고리의 다른 글

DTO에 대한 고민  (0) 2023.07.17
Mocktio - Spring 단위 테스트  (0) 2023.05.10
필터와 인터셉터  (0) 2023.04.07
Spring MVC 패턴  (0) 2023.03.30
쓰레드 풀을 이용한 쓰레드 관리  (0) 2023.03.26