Java EE test (CDI / interceptor) with Arquillian

Overview

Let's test Java EE with Arquillian, the Java EE testing framework. It is convenient because CDI and interceptor can be operated locally without preparing a Java EE server.

The source used this time is uploaded to Github. https://github.com/tuto00/Arquillian

Target audience

JavaEE test beginner

Preparation

Maven Edit pom.xml to use Maven. Add JavaEE, Junit, Arquillian library dependencies.

pom.xml


	<dependencies>
		<dependency>
			<groupId>org.jboss.spec</groupId>
			<artifactId>jboss-javaee-7.0</artifactId>
			<version>1.0.3.Final</version>
			<type>pom</type>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.arquillian</groupId>
			<artifactId>arquillian-bom</artifactId>
			<version>1.4.0.Final</version>
			<scope>import</scope>
			<type>pom</type>
		</dependency>
		<dependency>
			<groupId>org.jboss.arquillian.junit</groupId>
			<artifactId>arquillian-junit-container</artifactId>
			<version>1.4.0.Final</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.arquillian.container</groupId>
			<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
			<version>1.0.0.CR9</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.jboss.weld</groupId>
			<artifactId>weld-core</artifactId>
			<version>2.3.5.Final</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.6.4</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

beans.xml Please prepare because you want to use the interceptor.

beans.xml


<?xml version="1.0" ?>
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    version="1.1"
    bean-discovery-mode="all">

     <interceptors>
        <class>org.arquillian.interceptor.TraceInterceptor</class>
    </interceptors>

</beans>

Implementation

Inject the Hello class into the GreetService class. In addition, Interceptor (SampleInterceptor) is applied to GreetService class, and log output is performed before and after method execution.

GreetService.java


@Named
@ApplicationScoped
@SampleInterceptor
public class GreetService {

	@Inject
	Hello hello;

    public String greet(){
    	return hello.hello();
    }
}

@ApplicationScoped is also added to the Hello class to make it a CDI managed bean.

Hello.java


@ApplicationScoped
public class Hello {

	public String hello() {
		return "helloWorld";
	}
}

Next, identify the Interceptor and create annotations to execute it.

SampleInterceptor.java


@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface SampleInterceptor {
}

Then, prepare the following in the form of implementing the SampleInterceptor created above. The class name and method name are output before the method is executed.

TraceInterceptor.java


@Interceptor
@SampleInterceptor
public class TestInterceptor {
	@AroundInvoke
	public Object obj(InvocationContext ic) throws Exception {

		//Before executing the method
		System.out.println("process start class :" + ic.getTarget().getClass().getSimpleName()
				+ " method:" + ic.getMethod().getName());

		//Method execution
		Object result = ic.proceed();

		//After executing the method
		System.out.println("process end");

		return result;
	}
}

Test code

Finally I will use the main subject Arquillian. I will write the test code.

GreetServiceTest.java


@RunWith(Arquillian.class)
public class GreetServiceTest {

	@Inject
	GreetService greeter;

	@Deployment
	public static JavaArchive createDeployment() {
		JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
				.addPackage("org.arquillian.example")
				.addPackage("org.arquillian.annotation")
				.addPackage("org.arquillian.interceptor")
				.addAsManifestResource(new File("src/main/webapp/WEB-INF/beans.xml"));
		System.out.println(jar.toString(true));
		return jar;
	}

	@Test
	public void should_create_greeting() {
		assertEquals("helloWorld", greeter.greet());
	}
}

Unlike normal Junit, there are two points when using Arquillian.

The movement is as follows.

The @RunWith annotation tells JUnit to use Arquillian as the test controller. Arquillian looks for public static methods with the @Deployment annotation to receive test archives (that is, microdeployments). Then magic happens and each @Test method is executed inside the container environment.

The point is that you created a jar and ran it in a container. The container is controlled by Arquillian's container adapter. This time we are using Weld as the container and arquillian-weld-ee-embedded-1.1 as the container adapter.

Test run

Now let's run the test. Just like normal Junit, just run the test class in Junit.

Make sure the test result turns green and you see the following output on the console:

588b9820-a6f0-4ffe-b6bd-e8228bc24b98.jar:
/org/
/org/arquillian/
/org/arquillian/example/
/org/arquillian/example/Hello.class
/org/arquillian/example/GreetService.class
/org/arquillian/example/GreeterTest.class
/org/arquillian/annotation/
/org/arquillian/annotation/SampleInterceptor.class
/org/arquillian/interceptor/
/org/arquillian/interceptor/TraceInterceptor.class
/META-INF/
/META-INF/beans.xml
INFO: WELD-000900: 2.3.5 (Final) [Sun 6 23 18:06:32 JST 2019]
process start class :GreetService$Proxy$_$$_WeldSubclass method:greet
process end

You can see that process start, process end and interceptor are applied.

in conclusion

Arquillian makes it easy to test CDI and intercptor. Please try it out.

The downside is the lack of documentation. .. ..

Reference URL

Arquillian Guides

Recommended Posts

Java EE test (CDI / interceptor) with Arquillian
Build an E2E test environment with Selenium (Java)
Enable Java EE with NetBeans 9
[Java EE] Implement Client with WebSocket
[Java] Test private methods with JUnit
One-JAR Java EE application with WebSphere Liberty
Java automated test implementation with JUnit 5 + Gradle
Primality test Java
[Java] How to test for null with JUnit
[CircleCI 2.0] [Java] [Maven] [JUnit] Aggregate JUnit test results with CircleCI 2.0
Java automated test implementation with JUnit 5 + Apache Maven
Build and test Java + Gradle applications with Wercker
Compile with Java 6 and test with Java 11 while running Maven on Java 8
Create an E2E test environment with Docker x Cypress
Serverless Java EE starting with Quarkus and Cloud Run
Install java with Homebrew
Integration Test with Gradle
Change seats with java
Install Java with Ansible
Comfortable download with JAVA
Java Unit Test Library-Artery-Sample
Switch java with direnv
[Rails] Test with RSpec
Test Nokogiri with Rspec.
Download Java with Ansible
Automatically test with Gauge
Load test with JMeter
Let's scrape with Java! !!
Unit test with Junit.
Build Java with Wercker
Endian conversion with JAVA
I tried to modernize a Java EE application with OpenShift.
[Java] I want to test standard input & standard output with JUnit