This example shows how to write junit test for a method that returns Mono.
StepVerifier from io.projectreactor.reactor-test is used to test reactive components.
Below is the Service class that returns Mono.
BookService.java
package com.kswaughs.webflux;
import com.kswaughs.webflux.model.Book;
import reactor.core.publisher.Mono;
public class BookService {
public Mono<Book> getBookById(int bookId) {
if(bookId == 0) {
return Mono.error(new Exception("Invalid BookId"));
}
if(bookId == 100) {
return Mono.just(buildBook(bookId));
}
return Mono.empty();
}
private Book buildBook(int bookId) {
Book book = new Book();
book.setBookId(bookId);
book.setAuthor("John Grisham");
book.setTitle("A Painted House");
return book;
}
}
Below is the Junit test class to test Mono using StepVerifier
SpringWebFluxMonoExampleTest.java
package com.kswaughs.webflux;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import reactor.test.StepVerifier;
public class SpringWebFluxMonoExampleTest {
private BookService bookService = new BookService();
@Test
public void whenBookExists() {
StepVerifier.create(bookService.getBookById(100))
.assertNext(book -> {
assertEquals(Integer.valueOf(100), book.getBookId());
assertEquals("John Grisham", book.getAuthor());
assertEquals("A Painted House", book.getTitle());
}).verifyComplete();
}
@Test
public void whenBookNotExists() {
StepVerifier.create(bookService.getBookById(56))
.verifyComplete();
}
@Test
public void whenBookIdIsInvalid() {
StepVerifier.create(bookService.getBookById(0))
/** case 1: To validate only Exception className **/
//.expectError(Exception.class)
/** case 2: To validate only exception message **/
//.expectErrorMessage("Invalid BookId")
/** case 3: To Validate complete exception object **/
.expectErrorSatisfies(thr -> {
assertTrue(thr instanceof Exception);
assertEquals("Invalid BookId", thr.getMessage());
})
.verify();
}
}
pom.xml
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>