Tuesday 3 January 2023

Test Micronaut app with Micronaut client

This is continuation to my previous post. In this post, I am going to test the Hello world app that we developed in previous post.

 

Micronaut HTTP Client

Micronaut provides a Http client, that helps in executing HTTP requests and receiving HTTP responses.

 

How to obtain a HTTP Client?

Using @Client annotation, we can obtain an instance of HTTP Client.

@Client("/")
HttpClient client;

 

Test class definition

@MicronautTest
public class HelloWorldControllerTest {

	@Inject
	EmbeddedServer server;

	@Inject
	@Client("/")
	HttpClient client;

	@Test
	void testHelloWorldResponse() {
		String response = client.toBlocking().retrieve(HttpRequest.GET("/hello"));
		assertEquals("Hello World", response);
	}
}

 

a.   EmbeddedServer is a general abstraction to manage the lifecycle of any server implementation within a running Micronaut application.

b.   Since /hello is a blocking API, The test uses the toBlocking() method to make a blocking call.

c.    The retrieve method returns the controller response as a String

 

Write the test in more declarative way

Define an interface annotated with @Client.

 

for example:

 

@Client("/hello")
public interface HelloWorldClient {

	@Get(consumes = MediaType.TEXT_PLAIN)
	@SingleResult
	Publisher<String> hello();
}

 

a.   @Client annotation is used with a value that is a relative path to the current server

b.   @Get annotation used on the server is used to define the client mapping

c.    Publisher annotated with SingleResult is returned with the value read from the server

 

Now, we can test the /hello api using HelloWorldClient instance.

@MicronautTest 
public class HelloWorldControllerTestDeclarative {
	@Inject
    HelloWorldClient client; 

    @Test
    public void testHelloWorldResponse(){
        assertEquals("Hello World", Mono.from(client.hello()).block());
    }
}

Follow below step-by-step procedure to build complete working application.

 

Step 1: Create new maven project ‘hello-world-micronaut-client’.

 

Step 2: Update pom.xml with maven 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.sample.app</groupId>
	<artifactId>hello-world-micronaut-client</artifactId>
	<version>1</version>

	<parent>
		<groupId>io.micronaut</groupId>
		<artifactId>micronaut-parent</artifactId>
		<version>3.7.0</version>
	</parent>

	<properties>
		<packaging>jar</packaging>
		<jdk.version>11</jdk.version>
		<release.version>11</release.version>
		<micronaut.version>3.7.0</micronaut.version>
		<micronaut.runtime>netty</micronaut.runtime>
		<exec.mainClass>com.sample.app.App</exec.mainClass>
	</properties>

	<repositories>
		<repository>
			<id>central</id>
			<url>https://repo.maven.apache.org/maven2</url>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-inject</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-validation</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-http-client</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-http-server-netty</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut</groupId>
			<artifactId>micronaut-jackson-databind</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>jakarta.annotation</groupId>
			<artifactId>jakarta.annotation-api</artifactId>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>io.micronaut.test</groupId>
			<artifactId>micronaut-test-junit5</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-api</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>io.micronaut.build</groupId>
				<artifactId>micronaut-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Step 3: Define HelloWorldController class.

 

HelloWorldController.java

package com.sample.app.controller;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller("/hello")
public class HelloWorldController {

	@Get(produces = MediaType.TEXT_PLAIN)
	public String index() {
		return "Hello World";
	}
}

Step 4: Define main application class.

 

App.java

package com.sample.app;

import io.micronaut.runtime.Micronaut;

public class App {
	public static void main(String[] args) {
		Micronaut.run(App.class, args);
	}
}

Step 5: Define HelloWorldClient in src/test/java.

 

HelloWorldClient.java

package com.sample.app.client.interfaces;

import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.client.annotation.Client;
import org.reactivestreams.Publisher;
import io.micronaut.core.async.annotation.SingleResult;

@Client("/hello")
public interface HelloWorldClient {

	@Get(consumes = MediaType.TEXT_PLAIN)
	@SingleResult
	Publisher<String> hello();
}

Step 6: Define test classes.

 

HelloWorldControllerTest.java

package com.sample.app.controller;

import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;

import jakarta.inject.Inject;

import static org.junit.jupiter.api.Assertions.assertEquals;

@MicronautTest
public class HelloWorldControllerTest {

	@Inject
	EmbeddedServer server;

	@Inject
	@Client("/")
	HttpClient client;

	@Test
	void testHelloWorldResponse() {
		String response = client.toBlocking().retrieve(HttpRequest.GET("/hello"));
		assertEquals("Hello World", response);
	}
}

HelloWorldControllerTestDeclarative.java

package com.sample.app.controller;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

import com.sample.app.client.interfaces.HelloWorldClient;

import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import reactor.core.publisher.Mono;

@MicronautTest 
public class HelloWorldControllerTestDeclarative {
	@Inject
    HelloWorldClient client; 

    @Test
    public void testHelloWorldResponse(){
        assertEquals("Hello World", Mono.from(client.hello()).block());
    }
}

Total project structure looks like below.



How to run the test cases?

Navigate to the folder where pom.xml is located.

 

Execute below command to run the test class HelloWorldControllerTest

mvn -DTest=HelloWorldControllerTest test

 

Execute below command to run the test class HelloWorldControllerTestDeclarative

mvn -DTest=HelloWorldControllerTestDeclarative test

 

You can download the application from this link.


 

Previous                                                    Next                                                    Home

No comments:

Post a Comment