Getting an exception while mocking POST Web client

83 Views Asked by At

Controller

package com.bezkoder.springjwt.controllers;
    
    import com.bezkoder.springjwt.models.Product;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.reactive.function.client.WebClient;
    import org.springframework.web.util.UriComponentsBuilder;
    import reactor.core.publisher.Mono;
    
    import java.util.Arrays;
    import java.util.function.Consumer;
    
    @RestController
    public class ProductClientController {
    
        @Autowired
        WebClient webClient;
    
        @GetMapping("/catproducts")
        public String callSaveProductApi() {
            String response = null;
            Product product = new Product();
            product.setId(1l);
            product.setName("kumar2");
            product.setPrice(88);
            try {
                response = webClient.post()
                        .uri(UriComponentsBuilder.fromUriString("http://localhost:8080/products").build().toString())
                        .headers(getHttpHeadersConsumer()).body(Mono.just(product), Product.class)
                        .retrieve().bodyToMono(String.class).block();
    
            } catch (Exception e) {
                System.out.println(e);
            }
            return response;
    
        }
    
        private Consumer<HttpHeaders> getHttpHeadersConsumer() {
            return httpHeaders -> {
                httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            };
        }
    
    }

Controller Test

package com.bezkoder.springjwt.controllers;

import com.bezkoder.springjwt.models.Product;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

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

@ExtendWith(MockitoExtension.class)
public class ProductClientControllerTest {

    @InjectMocks
    ProductClientController productClientController;

    @Mock
    WebClient webClientMock;

    @Mock
    private WebClient.RequestBodyUriSpec requestBodyUriSpecMock;

    @Mock
    private WebClient.RequestBodySpec requestBodySpecMock;

    @Mock
    private WebClient.RequestHeadersUriSpec requestHeadersUriSpecMock;

    @Mock
    private WebClient.RequestHeadersSpec requestHeadersSpecMock;

    @Mock
    private WebClient.ResponseSpec responseSpecMock;
    @Test
    void callSaveProductApi(){
        Product product = new Product();
        product.setId(1l);
        product.setName("kumar2");
        product.setPrice(88);
        when(webClientMock.post())
                .thenReturn(requestBodyUriSpecMock);

        when(requestBodyUriSpecMock.uri(anyString()))
                .thenReturn(requestBodySpecMock);


        when(requestBodySpecMock.body(Mono.just(product), Product.class))
                .thenReturn(requestHeadersSpecMock);
        when(requestBodyUriSpecMock.headers(any())).thenReturn(requestBodySpecMock);

        when(requestHeadersSpecMock.retrieve())
                .thenReturn(responseSpecMock);

        when(responseSpecMock.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
                .thenReturn(Mono.just("success"));

        String s = productClientController.callSaveProductApi();
    }
     
}

Getting this exception while running the test

java.lang.NullPointerException: Cannot invoke "org.springframework.web.reactive.function.client.WebClient$RequestBodySpec.body(org.reactivestreams.Publisher, java.lang.Class)" because the return value of "org.springframework.web.reactive.function.client.WebClient$RequestBodySpec.headers(java.util.function.Consumer)" is null

2

There are 2 best solutions below

1
Carlene12War On
package com.bezkoder.springjwt.controllers;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

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

@ExtendWith(MockitoExtension.class)
public class ProductClientControllerTest {

    @InjectMocks
    ProductClientController productClientController;

    @Mock
    WebClient webClientMock;

    @Mock
    private WebClient.RequestBodyUriSpec requestBodyUriSpecMock;

    @Mock
    private WebClient.RequestBodySpec requestBodySpecMock;

    @Mock
    private WebClient.RequestHeadersSpec requestHeadersSpecMock;

    @Mock
    private WebClient.ResponseSpec responseSpecMock;
    @Test
    void callSaveProductApi(){
        when(webClientMock.post())
                .thenReturn(requestBodyUriSpecMock);

        when(requestBodyUriSpecMock.uri(anyString()))
                .thenReturn(requestBodySpecMock);

        when(requestBodySpecMock.headers(any())).thenReturn(requestBodySpecMock);
        when(requestBodySpecMock.body(any(Mono.class), any(Class.class))).thenReturn(requestHeadersSpecMock);

        when(requestHeadersSpecMock.retrieve())
                .thenReturn(responseSpecMock);

        when(responseSpecMock.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
                .thenReturn(Mono.just("success"));

        String s = productClientController.callSaveProductApi();
        System.out.println(s);
    }

}
0
sitan wen On

I encountered an empty pointer abnormality when running the test unit. Abnormal information pointed out that the Body method cannot be called because the return value of the Headers method is null. We can use Lenient to simulate the behavior:

lenient().when(requestBodyUriSpecMock.headers(any())).thenReturn(requestBodySpecMock);