Search code examples
javaspringspring-bootrestclient

Mocking RestClient using Mockito


I have a RestClient such as below:

SomeService.java:

String result = restClient.post().headers(httpHeaders -> httpHeaders.setBasicAuth(id,pwd))
                       .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                       .body(requestBody)
                       .retrieve()
                       .onStatus(HttpStatusCode::is4xxClientError, (request,response) -> {
                           throw new Exception(response.getStatusCode() + " : " + response.getHeaders());
                       })
                       .body(String.class);

I am trying to Mock this restClient call using Mockito to return a specific string. However this mock does not trigger. Am I missing anything?

SomeServiceTest.java:

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
RestClient restClient;

@Test
public void someTestMethod() {
    when(restClient.post().headers(any()).contentType(any()).body(any()).retrieve()
            .onStatus(any(),any()).body(String.class))
        .thenReturn("Some String");
}

On Execution, the mock does not trigger and the returned string is null in the service. Any help would be appreciated. Thank you.

I tried to mock the restClient call using Mockito and return a specific string. However, the mock does not trigger and hence a null string is returned. I am expecting the mock to trigger for the given method signature and return a specific string.


Solution

  • Thanks to the suggestions to mock individual method calls in the chain, I was able to resolve this issue. I used the below mocks and I was able to get the result. I had to remove the RETURNS_DEEP_STUBS and mock individual method calls in the chain. Thanks Matheus and Roman C for your suggestions.

    SomeServiceTest.java:

    @InjectMocks
    SomeService someService;
    @Mock
    RestClient restClient;
    
    @Test
    public void someTestMethod() {
        RestClient.RequestBodyUriSpec requestBodyUriSpec = mock(RestClient.RequestBodyUriSpec.class);
        RestClient.RequestBodySpec requestBodySpec = mock(RestClient.RequestBodySpec.class);
        RestClient.ResponseSpec responseSpec = mock(RestClient.ResponseSpec.class);
        when(restClient.post()).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.headers(any())).thenReturn(requestBodySpec);
        when(requestBodySpec.contentType(any())).thenReturn(requestBodySpec);
        when(requestBodySpec.body(anyMap())).thenReturn(requestBodySpec);
        when(requestBodySpec.retrieve()).thenReturn(responseSpec);
        when(responseSpec.onStatus(any(),any())).thenReturn(responseSpec);
        when(responseSpec.body(String.class)).thenReturn("Some String");
        String result = someService.callRestApi();
        assertEquals("Some String", result);
    }