Rupesh
Rupesh

Reputation: 1

Spring RestCleint.RequestBodyUriSpec body mocking returns null

Mocking RestClient.RequestBodyUriSpec body. Mocking returns null when used in RestClient web service.

Test case as below -

package org.mytest.tests;

import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClient;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class RestClientTest {

    @Test
    void mockRestClientTest() {
        // Creating mocks for RestClient and its components
        RestClient restClient = mock(RestClient.class);


        RestClient.RequestBodyUriSpec requestBodyUriSpecMock = mock(RestClient.RequestBodyUriSpec.class);
        when(restClient.method(any())).thenReturn(requestBodyUriSpecMock);

        RestClient.RequestBodySpec requestBodySpecMock = mock(RestClient.RequestBodySpec.class);
        RestClient.ResponseSpec responseSpecMock = mock(RestClient.ResponseSpec.class);

        // Defining behavior for method chaining
        when(restClient.method(any())).thenReturn(requestBodyUriSpecMock);
        when(requestBodyUriSpecMock.uri(anyString())).thenReturn(requestBodySpecMock);
        when(requestBodySpecMock.headers(any())).thenReturn(requestBodySpecMock);

        when(requestBodySpecMock.headers(any()).body(any())).thenReturn(requestBodySpecMock);
        when(requestBodySpecMock.body(any())).thenReturn(requestBodySpecMock);
        when(requestBodySpecMock.body(any(), any())).thenReturn(requestBodySpecMock);
        when(requestBodyUriSpecMock.body(any(Object.class))).thenReturn(requestBodySpecMock);
        when(requestBodySpecMock.retrieve()).thenReturn(responseSpecMock);
        when(responseSpecMock.toEntity(String.class)).thenReturn(new ResponseEntity<>("responseBody", HttpStatus.OK));


        // Testing to retrieve the mock result
        RestClient.RequestBodySpec result = requestBodySpecMock.headers(any());
        System.out.println("Mock requestBodySpecMock.headers -> " + result);

        result = requestBodySpecMock.body(any());
        System.out.println("Mock requestBodySpecMock.body -> " + result);

        RestClient.ResponseSpec responseResult = requestBodySpecMock.retrieve();
        System.out.println("Mock requestHeadersSpecMock.retrieve -> " + responseResult);

        result = requestBodySpecMock.headers(any()).body(any());
        System.out.println("Mock requestBodySpecMock.headers.body -> " + result);

        RestClient.RequestBodySpec requestBodySpec = restClient.method(HttpMethod.POST)
                .uri("https://localhost/my-server/")
                .headers(
                        HttpHeaders::clear)
                .body("SomeBody");

        System.out.println("RequestBodySpec -> " + requestBodySpec);

        ResponseEntity<String> resultStr = restClient.method(HttpMethod.POST)
                .uri("https://localhost/my-server/")
                .headers(
                        HttpHeaders::clear)
                .body("Some Body")
                .retrieve()
                .toEntity(String.class);

        System.out.println(resultStr);
    }
}

Output of print statement :

Mock requestBodySpecMock.headers -> Mock for RequestBodySpec, hashCode: 836972194 Mock requestBodySpecMock.body -> Mock for RequestBodySpec, hashCode: 836972194 Mock requestHeadersSpecMock.retrieve -> Mock for ResponseSpec, hashCode: 556945462 Mock requestBodySpecMock.headers.body -> Mock for RequestBodySpec, hashCode: 836972194 RequestBodySpec -> null

RestClient.RequestBodySpec requestBodySpec = restClient.method(HttpMethod.POST)
                .uri("https://localhost/my-server/")
                .headers(
                        HttpHeaders::clear)
                .body("SomeBody");

Update : Answer from @Georgios Ikosidekas Rodriguez helped.

Mocking RequestBodyUriSpec body with String solved the issue.

Used - when(requestBodySpecMock.body(anyString())).thenReturn(requestBodySpecMock);

Not sure why any() doesn't work.

Upvotes: 0

Views: 116

Answers (1)

I was having the exact same issue, I mocked the full chain and it still had null. I found a work around, when mocking the .body(), mock it with a more specific matcher like this:

when(requestBodySpec.body(anyList())).thenReturn(requestBodySpec);

Upvotes: 0

Related Questions