In this previous tutorial, we have seen how to build CRUD REST APIs using Spring Boot, Spring WebFlux, and MongoDB NoSQL database.
In this tutorial, we will learn how to write Integration tests to test Spring WebFlux reactive CRUD REST APIs using WebTestClient.
WebClientTest is a non-blocking, reactive client for testing web servers that uses the reactive WebClient internally to perform requests and provides a fluent API to verify responses.
WebTestClient contains request methods that are similar to WebClient. In addition, it contains methods to check the response status, header, and body. You can also use assertion libraries like AssertJ with WebTestClient.
Set up the Integration Tests Class
Let's create a base to write Integration test cases for Reactive CRUD REST APIs using WebClientTest:
import net.javaguides.springboot.repository.EmployeeRepository;
import net.javaguides.springboot.service.EmployeeService;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import java.util.Collections;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class EmployeeControllerIntegrationTests {
@Autowired
private EmployeeService employeeService;
@Autowired
private WebTestClient webTestClient;
@Autowired
private EmployeeRepository employeeRepository;
@BeforeEach
public void before(){
System.out.println("Before Each Test");
employeeRepository.deleteAll().subscribe();
}
}
Write an Integration Test for Add Employee REST API
Here is the Integration test case to test reactive Save Employee REST API:
@Test
public void testSaveEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("John");
employeeDto.setLastName("Cena");
employeeDto.setEmail("john@gmail.com");
webTestClient.post().uri("/api/employees")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(employeeDto), EmployeeDto.class)
.exchange()
.expectStatus().isCreated()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.firstName").isEqualTo(employeeDto.getFirstName())
.jsonPath("$.lastName").isEqualTo(employeeDto.getLastName())
.jsonPath("$.email").isEqualTo(employeeDto.getEmail());
}
Write an Integration Test to Get Employee REST API
Here is the Integration test case to test reactive Get Employee REST API:
@Test
public void testGetSingleEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Meena");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("meena@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
webTestClient.get().uri("/api/employees/{id}", Collections.singletonMap("id",savedEmployee.getId()))
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.id").isEqualTo(savedEmployee.getId())
.jsonPath("$.firstName").isEqualTo(employeeDto.getFirstName())
.jsonPath("$.lastName").isEqualTo(employeeDto.getLastName())
.jsonPath("$.email").isEqualTo(employeeDto.getEmail());
}
Write an Integration Test for Get All Employees REST API
Here is the Integration test case to test reactive Get All Employees REST API:
@Test
public void testGetAllEmployees(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("John");
employeeDto.setLastName("Cena");
employeeDto.setEmail("john@gmail.com");
employeeService.saveEmployee(employeeDto).block();
EmployeeDto employeeDto1 = new EmployeeDto();
employeeDto1.setFirstName("Meena");
employeeDto1.setLastName("Fadatare");
employeeDto1.setEmail("meena@gmail.com");
employeeService.saveEmployee(employeeDto1).block();
webTestClient.get().uri("/api/employees")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBodyList(EmployeeDto.class)
.consumeWith(System.out::println);
}
Write an Integration Test for Update Employee REST API
Here is the Integration test case to test reactive Update Employee REST API:
@Test
public void testUpdateEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Ramesh");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("ramesh@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
EmployeeDto updatedEmployee = new EmployeeDto();
updatedEmployee.setFirstName("Ram");
updatedEmployee.setLastName("Jadhav");
updatedEmployee.setEmail("ram@gmail.com");
webTestClient.put().uri("/api/employees/{id}", Collections.singletonMap("id", savedEmployee.getId()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(updatedEmployee), EmployeeDto.class)
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.firstName").isEqualTo(updatedEmployee.getFirstName())
.jsonPath("$.lastName").isEqualTo(updatedEmployee.getLastName())
.jsonPath("$.email").isEqualTo(updatedEmployee.getEmail());
}
Write an Integration Test for Delete Employee REST API
Here is the Integration test case to test reactive Delete Employee REST API:
@Test
public void testDeleteEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Ramesh");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("ramesh@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
webTestClient.delete().uri("/api/employees/{id}", Collections.singletonMap("id", savedEmployee.getId()))
.exchange()
.expectStatus().isNoContent()
.expectBody()
.consumeWith(System.out::println);
}
Complete Code to Test Reactive CRUD REST APIs using WebClientTest Class
We are using the below WebTestClient class method to prepare CRUD REST API requests:
post() - Prepare an HTTP POST request.
delete() - Prepare an HTTP DELETE request.
get() - Prepare an HTTP GET request.
put() - Prepare an HTTP PUT request.
Here is the complete code for testing Spring WebFlux Reactive CRUD Rest APIs using WebTestClient:
package net.javaguides.springboot;
import net.javaguides.springboot.dto.EmployeeDto;
import net.javaguides.springboot.repository.EmployeeRepository;
import net.javaguides.springboot.service.EmployeeService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Collections;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class EmployeeControllerIntegrationTests {
@Autowired
private EmployeeService employeeService;
@Autowired
private WebTestClient webTestClient;
@Autowired
private EmployeeRepository employeeRepository;
@BeforeEach
public void before(){
System.out.println("Before Each Test");
employeeRepository.deleteAll().subscribe();
}
@Test
public void testSaveEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("John");
employeeDto.setLastName("Cena");
employeeDto.setEmail("john@gmail.com");
webTestClient.post().uri("/api/employees")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(employeeDto), EmployeeDto.class)
.exchange()
.expectStatus().isCreated()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.firstName").isEqualTo(employeeDto.getFirstName())
.jsonPath("$.lastName").isEqualTo(employeeDto.getLastName())
.jsonPath("$.email").isEqualTo(employeeDto.getEmail());
}
@Test
public void testGetSingleEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Meena");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("meena@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
webTestClient.get().uri("/api/employees/{id}", Collections.singletonMap("id",savedEmployee.getId()))
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.id").isEqualTo(savedEmployee.getId())
.jsonPath("$.firstName").isEqualTo(employeeDto.getFirstName())
.jsonPath("$.lastName").isEqualTo(employeeDto.getLastName())
.jsonPath("$.email").isEqualTo(employeeDto.getEmail());
}
@Test
public void testGetAllEmployees(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("John");
employeeDto.setLastName("Cena");
employeeDto.setEmail("john@gmail.com");
employeeService.saveEmployee(employeeDto).block();
EmployeeDto employeeDto1 = new EmployeeDto();
employeeDto1.setFirstName("Meena");
employeeDto1.setLastName("Fadatare");
employeeDto1.setEmail("meena@gmail.com");
employeeService.saveEmployee(employeeDto1).block();
webTestClient.get().uri("/api/employees")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBodyList(EmployeeDto.class)
.consumeWith(System.out::println);
}
@Test
public void testUpdateEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Ramesh");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("ramesh@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
EmployeeDto updatedEmployee = new EmployeeDto();
updatedEmployee.setFirstName("Ram");
updatedEmployee.setLastName("Jadhav");
updatedEmployee.setEmail("ram@gmail.com");
webTestClient.put().uri("/api/employees/{id}", Collections.singletonMap("id", savedEmployee.getId()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(updatedEmployee), EmployeeDto.class)
.exchange()
.expectStatus().isOk()
.expectBody()
.consumeWith(System.out::println)
.jsonPath("$.firstName").isEqualTo(updatedEmployee.getFirstName())
.jsonPath("$.lastName").isEqualTo(updatedEmployee.getLastName())
.jsonPath("$.email").isEqualTo(updatedEmployee.getEmail());
}
@Test
public void testDeleteEmployee(){
EmployeeDto employeeDto = new EmployeeDto();
employeeDto.setFirstName("Ramesh");
employeeDto.setLastName("Fadatare");
employeeDto.setEmail("ramesh@gmail.com");
EmployeeDto savedEmployee = employeeService.saveEmployee(employeeDto).block();
webTestClient.delete().uri("/api/employees/{id}", Collections.singletonMap("id", savedEmployee.getId()))
.exchange()
.expectStatus().isNoContent()
.expectBody()
.consumeWith(System.out::println);
}
}
Output:
Here is the output of all the JUnit test cases:
Conclusion
In this tutorial, we have seen how to write Integration tests to test Spring WebFlux reactive CRUD REST APIs using WebTestClient.
Comments
Post a Comment
Leave Comment