Unit testing Java HttpClient with MockWebServer from OkHttp
Hello everyone, here you will learn unit testing Java HttpClient with MockWebServer from OkHttp. The Source code download link is provided at the end of this tutorial.
- The HTTP Client was added in Java 11 onwards. It can be used to request HTTP resources over the network. It fortifies HTTP/1.1 and HTTP/2, both synchronous and asynchronous programming models, handles request and replication bodies as reactive-streams, and follows the familiar builder pattern.
- MockWebServer makes it possible to facilely test how our apps comport when making HTTP/HTTPS calls. A mock web server is a program that mocks the behaviour of an actual remote server but doesn't make calls over the internet world.
Technologies Used:
- Java 17
- OkHttp MockWebServer
- Maven 3+
- jackson databinder
Final project directory:
Okhttp mockwebserver and jackson databinder dependencies
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
</dependencies>
Post.java
From Java 14 onwards, the record is a special type of class declaration aimed at reducing the boilerplate code.
package com.knf.dev.demo.javahttpclientokhttpunitestdemo.client;
public record Post
(String userId, String id, String body, String title) {
}
PostClient.java
package com.knf.dev.demo.javahttpclientokhttpunitestdemo.client;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PostClient {
private final String baseUrl;
HttpClient client;
HttpRequest request;
public PostClient(String baseUrl) {
this.baseUrl = baseUrl;
}
public List<Post> fetchAllPosts()
throws InterruptedException, IOException {
HttpClient client=HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().
uri(URI.create(baseUrl + "/posts"))
.header("Accept", "application/json")
.GET().build();
HttpResponse<String> response = client.
send(request, HttpResponse.BodyHandlers.
ofString());
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(response.body(),
objectMapper.getTypeFactory().
constructCollectionType(List.class, Post.class));
}
}
Test [PostClientTest:]
package com.knf.dev.demo.javahttpclientokhttpunitestdemo.client;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
public class PostClientTest {
private MockWebServer mockWebServer;
private PostClient post;
private static String RESPSONE_ALL;
static {
try {
RESPSONE_ALL = new String(
(PostClient.class.getClassLoader().
getResourceAsStream
("posts-all-success.json"))
.readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
@Before
public void init() {
this.mockWebServer = new MockWebServer();
this.post = new PostClient(mockWebServer.url("/").
toString());
}
@Test
public void fetchAllPosts()
throws InterruptedException, IOException {
mockWebServer.enqueue(new MockResponse().
addHeader("Content-Type", "application/json; "
+ "charset=utf-8")
.setBody(RESPSONE_ALL).setResponseCode(200));
List<Post> result = post.fetchAllPosts();
assertEquals(2, result.size());
assertEquals("title 1", result.get(0).title());
assertEquals("1", result.get(0).userId());
}
@After
public void aftertest() {
try {
mockWebServer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Test resource - posts-all-success.json
[
{
"userId": 1,
"id": 1,
"title": "title 1",
"body": "body 1"
},
{
"userId": 1,
"id": 2,
"title": "title 2",
"body": "body 2"
}
]
Execute unit test:
Github repository download link is provided at the end of this tutorial
Step 1: Download or clone the source code to a local machine.
Step 2: mvn clean install
mvn install will invoke mvn validate, mvn compile, mvn test, mvn package etc.