Reactive Spring Boot with R2DBC with TDD using PostGreSql

git repo: https://github.com/abhinav1singhal/employee-data-api.git

This article is about my hands on experience top develop a reactive sprint boot application using Test driven approach. These days TDD is a good idea to quickly show the concept move from an idea to a proved concept via CI/CD quickly.

This article assumes that you have good knowledge of how spring boot works and you have a initial setup of application.

Some basic setup should have Spring boot 2.3.1 or higher , spring boot reactive Web , Java 11, lombok, contract verifier, Spring data R2dbc, postgresql driver

It will look something like this

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

now open the code in IDE of your choice and make sure you have all the imports done properly.

Now lets start coding using TDD. My application is called EmployeeDataApiApplication so you will see it created EmployeeDataApiApplicationTests. Delete this Tests class

Create a class Test class in Test package EmployeeTest.java under com.reactive.employeedataapi package

write a test case using @Test annotation. You can declare Employee and it will give error as Employee class doesnt exists. This will force us to create an Employee class in the main application.

Employee class can be created like this using Lombok

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {

@Id
private Integer id;
private String firstName;
private String LastName;

}

@Id is from org.springframework.data.annotation.Id;

Now Lets move back to our testcase and complete the tests

public class EmployeeTest {
@Test
public void test_createEmployeeBean(){

Employee employee=new Employee(1001,"Jack", "Smith");
Assertions.assertEquals(employee.getId(),1001);
Assertions.assertEquals(employee.getFirstName(),"Jack");
Assertions.assertEquals(employee.getLastName(),"Smith");
}
}

This is very simple test case and should work.

Lets now try to create Test cases to Test our Repositories, so for that lets create test class under a new repository package called EmployeeRepositoryTests and try to create a persist code something like this. You can see that since we do not have the employeeRepository in our code it will give an error and that indicates we need to create a repsitory.

create and EmployeeRepository in main application under the package repository

public interface EmployeeRepository extends ReactiveCrudRepository<EmployeeRepository, Integer> {
}

now since we are working on R2DBC and postGreSQL, I am assuming you have created a postGreSQL server DB and have a table called Employee.

The connection in application.yml file will looks like this



spring:
r2dbc:
url: r2dbc:postgres://localhost/emp
username: postgres
password: *******

Now lets go back to EmployeeREpositoryTests class and add the annotations @ExtendWith(SpringExtension.class) and @DataR2dbcTest .We are using @ExtendWith( SpringExtension.class ) to support testing in Junit 5. In Junit 4, we need to use @RunWith(SpringRunner.class).

@ExtendWith(SpringExtension.class)
@DataR2dbcTest
public class EmployeeRepositoryTests {

@Autowired
EmployeeRepository employeeRepository;

@Test
public void tests_persisEmployee(){

Flux<Employee> actual = this.employeeRepository.deleteAll()
.thenMany(this.employeeRepository.save(new Employee(null, "Tina", "Fey")))
.thenMany(this.employeeRepository.findAll());

StepVerifier.create(actual)
.expectNextMatches(result->result.getFirstName().equalsIgnoreCase("tina"))
.verifyComplete();
}

}

This concludes the Repository test API. The next Article will include the Resource layer i.e. Controller testing using the same project.