fbpx

Builder Design Pattern

What is Builder Design Pattern ? Why we should care about it ?

Starting from Creational Design Pattern, so wikipedia says “creational design pattern are design pattern that deals with object creation mechanism, trying to create objects in manner that is suitable to the situation”.


The basic form of object creations could result in design problems and result in complex design problems, so to overcome this problem Creational Design Pattern somehow allows you to create the object.

Builder is one of the Creational Design Pattern.

When to consider the Builder Design Pattern ?

Builder is useful when you need to do lot of things to build an Object. Let’s imagine DOM (Document Object Model), so if we need to create the DOM, We could have to do lot of things, appending plenty of nodes and attaching attributes to them. We could also imagine about the huge XML Object creation where we will have to do lot of work to create the Object. A Factory is used basically when we could create the entire object in one shot.

As Joshua Bloch (He led the Design of the many library Java Collections Framework and many more) – “Builder Pattern is good choice when designing the class whose constructor or static factories would have more than handful of parameters

While considering the pattern you need to look whether Object is having –

1. Complex Constructor : Multiple constructor having multiple parameters with nested Object. Let’s say you love Pizza (PS : I Love Burger ) . We might have encountered time in where we need customise Object(pizza).

This is called Telescoping Constructor Pattern and problem with this is once constructor have more than 4-5 arguments it is hard to remember the order of parameters. (Although some IDE solves this problems)

One alternative to this problem is we could use JAVABean Pattern where you call constructor with required argument and use setter afterwards –

The Problem is with that Object is created on several calls, it may be in inconsistent state partway through its construction.

2. Large Number of Parameter – Having large number of parameters is also key point to consider.

3. Immutability – You could force the immutability to the object once it is done.

Let’s see any example and learn how to implement the builder pattern :

Things are simple when we have 4-5 parameters but eventually becomes messy when we have more than this.

Convert to Builder Pattern : Let’s now add extra fields to the to the POJO and convert it into Builder Design. Create the static anonymous inner class name Builder to the POJO, why static because we want to return or use the current object. Add same fields of POJO and setter of each field with return type of Builder Class. Lastly add the build() method which will return the Object of our POJO.

The resulting builder create code:

Pros :

  1. Code is more readable and maintainable if number of property are more than 4-5 in class.
  2. You can force the Immutability to the Object by not creating the setter() in POJO and only allowing the getter() in POJO.
  3. Robustness to the code as fully constructed object will be available always.

Cons :

  1. It increases the code duplication in the class well it can be improved with library like Project Lombok.

So How was your Pizza, Keep Building, Keep Coding.

Connect with us at LinkedIn –


Upcasting and DownCasting In Java

Upcasting and DownCasting In Java:-

It is one of the most popular interview questions in Java. We will talk about  Up casting and Down Casting in Java. Let’s have a look at the problem or rather question.

class Animal
{ 
    public void callme()
    {
      System.out.println("Called Human");
    }
}


class Man extends Animal
{ 
    
    public void callme2()
    {
        System.out.println("Called Man Call2");
    }
}

public class Test
{
    public static void main (String [] args) 
    {
       Animal animal = new Man(); /---- Point 1
       Man man=new Animal(); /--- point 2
       man.callme2()
    }
}

What would be the Output ? If you know the answer then i think you are not the target audience here and you can skip this post.

Answer:-

For Point 2 there will be a compilation Error as well as runtime error.

Let’s discuss why ?

What is Upcasting & Downcasting Here:-

Upcasting is casting to a supertype, while downcasting is casting to a subtype. Upcasting is always allowed, but downcasting involves a type check and can throw a ClassCastException.

In your case, a cast from Man to an Animal is an upcast, because of a Man is-a Animal In general, you can upcast whenever there is an is-a relationship between two classes.

We will now resolve both the  Issues.

1. Bypass Compilation Issue by Casting:-

So the Code Looks Like:-

        Animal animal = new Man();
        Man man=(Man) new Animal();
        man.callme2();

Here you Will get a ClassCastException The reason why is because animal‘s runtime type is,Animal .

Now at runtime, it performs the cast and it seems that animal isn’t really a Man and so throws a ClassCastException .

We can use the instanceof operator to check the runtime type of the object before performing the cast, which allows you to prevent ClassCastException.

Note: –We can use the instanceof operator to check the runtime type of the object before performing the cast, which allows you to prevent ClassCastException

We have basically done DownCasting here , thats the reason it looks messy and even not recommended in java to go for DownCasting . Lets Say if you have a cenario where you really want to go ahead with DownCasting in Java . You have to keep following point in mind

  1. Never Buy for Downcasting .
  2. Always Prefer doing instance of check in case of DownCasting .
  3. UpCasting in java is a Much Safer option always .

2. ByPass the Runtime Error:-

So the Updated and Corrected Code would look like,

Animal animal = new Man();
Man man= (Man) animal;

Explanation:-

So what happens here,

Basically, we are telling the compiler that we know runtime type of the object .Hence we don’t get a compilation error here.

There will not be any runtime error as , the cast is possible because at runtime animalis actually a Man even though the static type of animal is Animal.

Keep in mind , if there is an Inheritance with IS – A relationship we can do Upcasting in Java in every scenario.

Constructor Injection and Field Injection Misconception Cleared

constructor injection vs field injection

Constructor Injection and Field Injection Misconception Cleared:-

In this post i am gonna talk about Constructor and Field injection . It came out of a fight between me and my friend that Constructor Injections are better and we had a pretty much bad fight. It all started with this line in my code .

Lemme tell you one thing before we deep dive Constructor Injection and Field Injection is a debatable topic .

Let me know in comments what do you think .

@Autowired
private ClassA A;;

I used to be a huge fan of this piece of line . But I have been mistaken and I admit it .

I was aware of the dependency injection types  , but those differences seem to me good for interview or too much theoretical. It is possible that  I didn’t want to understand those in a deeper level .

Most of us are pretty much confident about writing a cleaner code and above line does makes our code clean . 


What Is Wrong :-

Using DI Containers we make sure that a class doesn’t have to manage its own dependencies , but here we are making our class to manage its own dependencies. Class should be more independent .Using a Constructor Injection here makes more sense.

Lets think of a scenario where your Service class has a field injected .Think a moment While writing test cases can you have a look a class and figure out the dependencies needed for the class ?? . No You cant , you have to go and explore the class , then you will be able to find out the dependencies used in your classes.

Now again , once you want to assign some mock values to your  private fields it is not easy .You have to setup a spring Context as Spring  can inject dependencies into private fields . You might need to use reflection in worst cases .

I know most people says reflection is common now a days , but my friend doing these , The Whole purpose of dependency injection goes for  a toss . As , the main purpose of DI was to write code that is easier to test and Write code that is highly decoupled.

Summarize What happens to Following Code :-

class MyService{
 
  @Autowired
  private ClassA A;
  
  public void doSomething() {
    A.doSomething();
  }
}

So basically what you are saying over here is :-

“I have this class with private state, to which I have attached @Autowired annotations, which means that the state can be automatically changed by some agent from the outside, even though my state has all been declared private.” 

Your JUNIT test cases starts breaking here as you will be doing below 

MyService service= new MyService();
service.doSomething(); // -> NullPointerException

You are allowing anyone to create a instance using default constructor and change state of your object which is not good.

How to Solve this :-

Well , we are going forward to explain Constructor Injection but  in terms of usability . Lets have a look at the solution of the above problem .

class MyService{
 
  private final ClassA A;
  
  @Inject
  public MyService(ClassA A) {
   
    this.A= A;
  }

  public void doSomething() {
    A.doSomething();
  }
}

Short Summary :-

  1. No null pointer as the class has the mandatory dependency provided at the time of creating object.
  2. Final fields adds too immutability here .
  3. As a consumer i know what all dependencies are required before creating object of this classs.
  4. Looks like a lot of code ? We can use Lombok to remove this boilerplate 
  5. If you feel you classes has a lot of dependencies , you probably need to rethink about your design and segregate your classes in different modules.




Have a Look In Case you Have a Frugalismind !

JPA EntityManager Example

JPA EntityManager Example:-

JPA EntityManager Example, we are going to find out how we can use the JPA Entity Manager to do operations on Database. It is the core of Java Persistence API. We are going to use Hibernate. Hibernate is one of the implementations of JPA. We generally use EntityManager in a JPA based application to interact with a persistence context.

The main advantage of using an EntityManager is that it does not bind  Spring to Hibernate. EntityManager is a part of JPA and any JPA based framework can be used for persistence.



JPA Entity Manager:-

  • It is used to interact withPersistence Context. The context consists a set of all entity instances.
  • The interface EntityManagerFactory is used by the application to obtain an application-managed Eentity Manager.
  • In ORM world entities are just like a table in the database. The EntityManager API  provides a set of API methods used to create, remove entity and query over entities.

JPA Entity Manager Example Code:-

Technologies Used:-

  • Java 1.8
  • Maven 3.3
  • Hibernate 5.2.6
  • Mysql

Project Dependencies:-

pom.xml:-

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.frugalis.entity</groupId>
	<artifactId>Entity-Manager-Example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>Entity Manager</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<!-- MySQL connector -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.5</version>
		</dependency>
		<!-- Hibernate 5.2.6 Final -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.2.6.Final</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<sourceDirectory>src/main/java</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Create Entity:-

We are going to create a simple bean with the name as Employee.This bean contains following properties.

  1. Id
  2. Name
package com.frugalis.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
	private int employeeId;

	private String name;

	@Id
	@Column(name = "EMPLOYEE_ID")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public int getEmployeeId() {
		return employeeId;
	}

	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}

	@Column(name = "EMPLOYEE_NAME")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Employee [ID=" + employeeId + ", Name=" + name + "]";
	}

}

As you can notice we are using annotation @Entity provided by JPA. This annotation identifies the POJO class as an Entity and to registers this class with the persistence context. Let’s configure our database before proceeding.



Configure Database for Persistence:-

We are going to create a file Persistence.xml and register the database for JPA.We are going to create a tag <persistance-unit>  andprovide a name for it under which all our configurations are defined.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
	version="2.1">

	<persistence-unit name="persistence">
		<description>JPA Entity Manager</description>
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test" />
			<property name="hibernate.hbm2ddl.auto" value="update" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="root" />
			<property name="hibernate.show_sql" value="true" />
		</properties>

	</persistence-unit>

</persistence>




Save, Update, Retrieve and Delete an Entity Using  JPA Entity Manager:-

  1. We are going to create a persistence unit by providing persistence unit name we provided in the XML using createEntityManagerFactory() method.
  2. The entityManagerFactory creates an instance of entity manager using createEntityManager() method.
  3. Each operation done by entityManager is wrapped under a transaction.The entityManager provides transaction object for transaction management.
  4. Use begin () method on entityManager transaction object to start the transaction.
  5. Use commit() method to save the transaction and persist the changes.
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence");
		EntityManager entityManager = entityManagerFactory.createEntityManager();

		entityManager.getTransaction().begin();
		Employee employee = new Employee();
		employee.setName("Sanjay");

                // Save Entity
		entityManager.persist(employee);
		entityManager.getTransaction().commit();
		System.out.println("Generated Employee ID = " + employee.getEmployeeId());

1. Retrieve an Entity using Primary Key:-

We got the employee Id from above step, hence using it to find the details and load from DB.

               //Reftrieve Enity from DB using Primary Key
		Employee emp = entityManager.find(Employee.class, employee.getEmployeeId());

2. Delete an Entity using JPA Entity Manager:-

We need to load Entity first from above step and then we remove the Entity.

            entityManager.getTransaction().begin();
		entityManager.remove(emp);
		entityManager.getTransaction().commit();

Close the Entity manager after your task is done

// close the entity manager
 entityManager.close();
 entityManagerFactory.close();

3. Writing Custom Query Using JPA Entity Manager:-

We can also write a custom query to query the entities we are writing.The syntax is quite similar to SQL but the only difference is SQL works directly on database tables but the JQL works on Java classes and Instances.We can do all operations that we generally do using SQL.

Let’s take a look using simple Query against our Employee entity.

//Select Query
List<Employee> emplList= entityManager.createQuery("SELECT e FROM Employee e").getResultList();

List<Employee> emplList= entityManager.createQuery("SELECT UPPER(e.name) FROM Employee e").getResultList();

In order to write type safe queries, JPA has an introduced Criteria Query which uses entities to write queries.

 

What’s New in JDK 10 – Features and Enhancements Java 10 ?

What’s New in JDK 10 – Features and Enhancements Java 10?

Java released its new version Java 10 recently. Java Standard Edition 10, was released on March 20, 2018.There are few updates in security, collections api and  garbage collection are  done in java .Let’s check some of the features and enhancements in Java 10.This release of JDK 10 is considered as a Short term release.The Long term Support (LTS) release of JDK 10 is due in September .We are going to discuss some highlighted features only .


Optional.orElseThrow()MethodJava:-

Java has added a new orElseThrow method in the optional class.Optional.get() seems tempting for developers leading to frequent errors . Its a kind of replacement for optional.get(). However optional.get() is not yet deprecated.



APIs for Creating Unmodifiable Collections:-

Features and Enhancements Java 10 has a new Api such as List.copyOfSet.copyOf, and Map.copyOf under java.util.collections package. Some new API are also added in Stream package such as toUnmodifiableListtoUnmodifiableSet, and toUnmodifiableMap .These allow the elements of a Stream to be collected into an unmodifiable collection.

List<String> list = List.of(...);
    List<CharSequence> newList = List.copyOf(list);

This can’t be done for mutable collections, since it can lead to heap pollution.





Bytecode Generation for Enhanced for Loop:-

If a huge list of array is iterated using for loop,it keeps a temporary reference to the memory .This memory might be locked for garbage collection , hence causing out of memory errors. Hence java team updated the byte code generation logic for this.

Parallel Full GC for G1:-

Java now has its GC as Parallel GC.The new G1 garbage collector is designed to avoid full collections, but when the concurrent collections can’t reclaim memory fast enough a fall back full GC will occur.With the new update of Java 10 G1 is  converted as parallel.

Some of the Features and Enhancements In Java 10 which are removed:-

  • Removal of Deprecated Classes in com.sun.security.auth.**
  • Removal of policy tool
  • Removal of Common DOM APIs
  • Removal of RMI Server-Side Multiplex Protocol Support
  • Removal of Runtime.getLocalizedInputStream and getLocalizedOutputStream Methods
  • Removal of Support for Using Old LookAndFeel
  • Removal of Deprecated Pre-1.2 SecurityManager Methods and Fields

Please visit this link from Oracle to  learn more about the variouss Features and enhancements in Java 10




CRUD Rest API With Spring Web-Flux Reactive Programming with Spring 5

CRUD Rest API With Spring Web-Flux Reactive Programming with Spring 5:-

Spring has released Reactive Web Framework and it is one of the hot topics in Spring world.Our controllers now run on Spring Reactive Engine. We will show a basic Spring Web-Flux Crud example.

Spring Framework 5 embraces Reactive Streams and Reactor for its own reactive use as well as in many of its core API’s.

Lets talk a bit about Reactive Programming and write CRUD Rest API With Spring Web-Flux Reactive Programming with Spring 5.

Spring Framework 5 includes a new spring-web-flux module. The module contains support for reactive HTTP and Web Socket clients as well as for reactive server web applications including REST, HTML browser, and Web Socket style interactions.Spring Web-flux supports two different programming models:-

  • Annotation-based with @Controller and the other annotations supported also with Spring MVC
  • Functional, Java 8 lambda style routing and handling

Below is the image that demonstrates the server side aspect of both the programming model.

Spring Reactive Programming

So Now, let’s go ahead and implement a CRUD Rest Service which would do all operations related to User Object and understand Spring reactive module a bit further.



Technologies used:-

  • Spring 5.
  • Spring Boot 2.
  • Eclipse 4.4.
  • JDK 1.8.

Project Dependencies:-

  • Spring Boot 2.0.
  • Spring Webflux.
  • Spring Reactive Data MongoDb.

Create Project :-

  • Navigate to start.spring.io
  • Enter Project Name and package name as required.
  • Select Reactive Web and Reactive MongoDb as Project Dependencies.
  • Click on generate .
  • Import Project in your favorite IDE and create following package structure as below.

Reactive Programming Spring boot MongoDB

Configure Your Application:-

We need to annotate our spring class with @EnableReactiveMongoRepositories .Any annotation in reactive spring based modules will start with Enable..followed by Reactive .

We finally activate Spring Data Reactive MongoDB JPA repositories using the @EnableReactiveMongoRepositories annotation which essentially carries the same attributes as the XML namespace does.

If no base package is configured it will use the one the configuration class resides in.

package com.frugalis.ReactiveRest;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;

@SpringBootApplication
@EnableReactiveMongoRepositories
public class ReactiveRestApplication {

	@Autowired
	UserRepository userRepository;
	
	public static void main(String[] args) {
		SpringApplication.run(ReactiveRestApplication.class, args);
	}
}

Let’s Configure MongoDB , we are going to use cloud-based MLAB .Please visit this link to understand setup MLAB .We are going to use mongo url in application.properties

spring.data.mongodb.uri=mongodb://<user>:<password>@ds163918.mlab.com:63918/spring

We are just going to use this as aproperty wee can also  mention db specific properties separately .Please visit this link Spring Boot MongoDB+MLAB to check that and understand.

Database Access Using Reactive MongoDB:-

We are going to first create a user entity model and that is going to persist in our MongoDB using Spring reactive based rest api call.

package com.frugalis.ReactiveRest.entity;

import java.io.Serializable;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;


@Document(collection = "Users")
public class Users implements Serializable {
	@Id
	int id;
	String name;
	String age;
	public Users() 
        {
	}
	public Users(String name, String age) {
		this.name = name;
		this.age = age;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
		
}

The Users class is annotated with @Document, indicating that it is a JPA entity. It is assumed that this entity will be mapped to a collection named Users.The User’s id property is annotated with @Id so that JPA will recognize it as the object’s ID.Lets create a repository which extends some core Spring data interface to helps us not to write query and do the stuff for you.



We write our repository to access database using Spring data provided marker interface Repository.We are going to use  @ReactiveMongoRepository which extends @ReactiveCrudRepository.These interfaces provides us with some basic operations needed such as save(), update(),findAll(),findById() etc.
we can also write templating methods which will internally generate query based on method signature.In above code we are writing a method findByName() which will write a query to select the collection based on name.

package com.frugalis.ReactiveRest.repository;

import org.springframework.data.mongodb.repository.ReactiveMongoRepository;

import com.frugalis.ReactiveRest.entity.Users;

import reactor.core.publisher.Flux;

public interface UserRepository extends ReactiveMongoRepository<Users, Integer> {

    Flux<Users> findByName(String name);

}

Understanding Flux and Mono in brief:-

We use Flux if we need to return a set of data  stream which can emit 0..N elements:

Flux<String> flux = Flux.just("a", "b", "c");

Mono is a stream of 0..1 elements:
Mono mono = Mono.just("Hii");

As we are returning a single person hence we have used Mono .

Writing Controller :-

package com.frugalis.ReactiveRest.Controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.frugalis.ReactiveRest.entity.Users;
import com.frugalis.ReactiveRest.repository.UserRepository;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/users")

public class UsersOldController {

	@Autowired
	UserRepository userRepository;
	
	@GetMapping
    public Flux<Users> getAllUser() {
        return userRepository.findAll();
    }
	
	@PostMapping
    public Mono<Users> createUser( @RequestBody Users user) {
        return userRepository.save(user);
    }

	@GetMapping("/{id}")
    public Mono<ResponseEntity<Users>> getUserById(@PathVariable(value = "id") int userId) {
        return userRepository.findById(userId)
                .map(savedTweet -> ResponseEntity.ok(savedTweet))
                .defaultIfEmpty(ResponseEntity.notFound().build());
    }
}

Using Router Functions:-

We use router functions to define our rest end points in functional way.We are going to understand the router functions in a separate article in detail.This is a basic simple use case of writing reactive router.

@Bean
    RouterFunction<ServerResponse> helloRouterFunction() {
		
        RouterFunction<ServerResponse> routerFunction =
                RouterFunctions.route(RequestPredicates.path("/"),
                        serverRequest ->
                                ServerResponse.ok().body(Mono.just("Hello World!"), String.class));

        return routerFunction;

}

Now, We want to load some data one our  spring boot Application starts .Lets update our MainApplication.java .

 @Bean
	CommandLineRunner runner() {
		return args -> {

			System.out.println("::::::::::::::::::::::");

			Mono<Void> sss = userRepository.deleteAll();

			sss.subscribe((e) -> {

			}, Throwable::printStackTrace);

			for (int i = 0; i <= 5; i++) {
				Users user= new Users("Test"+i, "1" + i);
				user.setId(i);

				Mono<Users> data = userRepository.save(user);
				System.out.println(data);

				data.subscribe((e) -> {
					System.out.println(e.toString());
				}, Throwable::printStackTrace);
			}
		};

We can see after returning mono from userRepository we have to subscribe , execution is going to happen only if you subscribe . As you know in my previous article Creating REST Service with Spring Boot   we saw how to test the code using postman .Please follow that to test using Postman.

Integration Testing Rest API:-

Now that we have created a CRUD Rest API With Spring Web-Flux Reactive Programming with Spring 5 .It is time to write some integration test.We are going to use WebTestClient .

It is a Non-blocking, reactive client for testing web servers. It uses the reactive WebClient internally to perform requests and provides a fluent API to verify responses. Run this test class using Junit .

package com.frugalis.ReactiveRest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;

import com.frugalis.ReactiveRest.entity.Users;
import com.frugalis.ReactiveRest.repository.UserRepository;

import reactor.core.publisher.Mono;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ReactiveRestApplicationTests {
	@Autowired
	private WebTestClient webTestClient;
	@Autowired
	private UserRepository userRepository;
	
		@Test
	public void saveUser() {
		Users ps=new Users("dsld", "dfdf");
		userRepository.deleteAll().subscribe();

		webTestClient.post().uri("/users")
				.contentType(MediaType.APPLICATION_JSON_UTF8)
                 .body(Mono.just(ps), Users.class)
				.exchange()
				.expectStatus().isOk()
				.expectHeader().valueEquals("Content-Type", MediaType.APPLICATION_JSON_UTF8.toString())
				.expectBody()
				.jsonPath("$.name").isEqualTo("dsld");      
               
	}

		@Test
		public void testUser() {
			webTestClient.get().uri("/users")
					.exchange()
					.expectStatus().isOk()
					.expectHeader().valueEquals("Content-Type", MediaType.APPLICATION_JSON_UTF8.toString())
					.expectBodyList(User.class).hasSize(1);
				     
	               
		}
}

Download Code