Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use MockWebServer for Junit test cases of webclient?

I have a spring-boot application which calls some third party URL (let's say http://example.com/someUri) using webclient(I have used application-dev.properties for injecting this url in my application to achieve loose coupling) and consumes the response and use it in my application.

It's my first time when I am going to write test cases for webclient. and there I used @SprintBootTest. I found that there are two ways where I can test my webclient with third party Api call by mocking the api call and make it call to my local url(which will be using url(http://localhost:{portNumber}/someUri) from my testing properties file: src/test/resources/application.properties) where It will be giving some mockedResponse in return to my real client:

  1. Using wiremock
  2. Using MockWebServer

consider above code for better understanding:

@Service
Class SampleService{
    
@Value("${sample.url}")
private String sampleUrl;

public String dummyClient() {
    String sample =webClient.get()
            .uri(sampleUrl)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .retrieve()
            .bodyToMono(String.class)
            .block();
    return sample;

    }
 }

application-dev.properties:

sample.url:http://example.com/someUri

src/test/resouces/application.properties:

http://localhost:8090/someUri

Testing class:

@SpringBootTest
public class sampleTestingClass {

@Autowired
private SampleService sampleService;

@Value("${sample.url}")
private String sampleUrl;

    public static MockWebServer mockWebServer = new MockWebServer();

    @BeforeAll
    static void setUp() throws IOException {
        mockWebServer.start(8090);
    }

    @AfterAll
    static void tearUp() throws IOException {
        mockWebServer.close();
    }

 HttpUrl url = mockWebServer.url("/someUri");
       
        mockWebServer
                .enqueue(
                new MockResponse()
                .setResponseCode(200)
                .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .setBody("Sample Successful")); 

      
        String sample = sampleService.dummyClient();
        assertEquals(sample ,matches("Sample Successful"));
    } 
}

but this code isn't working. it's giving me above error:

java.lang.NullPointerException 

It will be really helpful if anybody knows how this can be fixed to achieve my unit testing using mocked Url? Thanks in advance!

like image 488
Priyanka Wagh Avatar asked Oct 29 '25 13:10

Priyanka Wagh


1 Answers

Here is a working example:

@Component
public class QuotesClient {

  private final WebClient webClient;

  public QuotesClient(WebClient.Builder builder, @Value("${client.baseUrl}") String baseUrl) {
    this.webClient = builder.baseUrl(baseUrl).build();
  }

  public JsonNode getData() {
    return this.webClient
      .get()
      .retrieve()
      .bodyToMono(JsonNode.class)
      .block();
  }
}

Using the WebClient.Builder is optional.

The corresponding test can look like the following:

class QuotesClientTest {

  private QuotesClient quotesClient;
  private MockWebServer server;

  @BeforeEach
  public void setup() {
    this.server = new MockWebServer();
    this.quotesClient = new QuotesClient(WebClient.builder(), server.url("/").toString());
  }

  @Test
  public void test() {

    server.enqueue(new MockResponse()
      .setStatus("HTTP/1.1 200")
      .setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}")
      .addHeader("Content-Type", "application/json"));

    JsonNode data = quotesClient.getData();
    assertNotNull(data);

    System.out.println(data);

  }

}

If you are searching for a similar setup using WireMock, Spring Boot, and JUnit 5, take a look at the linked guide.

like image 190
rieckpil Avatar answered Oct 31 '25 11:10

rieckpil