Burak Aktas Software Engineer

Arquillian Example for CDI Dependency Injection

Arquillian is a platform which provides integration tests by deploying, running containers so that we can easily use cdi beans in tests. In this tutorial we will see how to inject and use cdi beans in test classes by running Arquillian.

As a first step we have to add Arquillian core library in our pom.xml in the dependencyManagement block. Well it is completely optional, and you can add it in dependencies section.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>1.1.5.Final</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

Afterwards, add Arquillian Junit container in our pom.xml in dependencies.

<dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <scope>test</scope>
    </dependency>

Finally, we have to add a container adapter and cdi dependency for that container.

<!-- Arquillian container adapter for the target container -->
    <dependency>
        <groupId>org.jboss.arquillian.container</groupId>
        <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
        <version>1.0.0.CR3</version>
        <scope>test</scope>
    </dependency>

    <!-- CDI dependency for container -->
    <dependency>
        <groupId>org.jboss.weld</groupId>
        <artifactId>weld-core</artifactId>
        <version>1.1.5.Final</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

Here you can find very simple classes that I am going to use for dependency injection with the directory structure.

.
├── pom.xml
├── src
   ├── main
   ├── java
   │   └── com
   │       └── buraktas
   │           ├── autoservice
   │               ├── AutoService.java
   │               ├── BMWAutoService.java
   │               ├── HondaAutoService.java
   │           
   ├── resources
   └── webapp
       └── WEB-INF
           └── beans.xml
AutoService.java
public interface AutoService {
    String getService();
}

BMWAutoService.java

@Named("bmwAutoService")
public class BMWAutoService implements AutoService{

    @Override
    public String getService() {
        return "You chose BMW auto service";
    }
}

HondaAutoService.java

@Named("hondaAutoService")
public class HondaAutoService implements AutoService{

    @Override
    public String getService() {
        return "You chose Honda auto service";
    }
}

Finally, we can implement and test our cdi beans by using Arquillian platform.

@RunWith(Arquillian.class)
public class AutoServiceTest {

    @Deployment
    public static WebArchive createJavaTestArchive() {

        return ShrinkWrap.create(WebArchive.class)
                .addPackage("com.buraktas.autoservice")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Inject
    @Named("bmwAutoService")
    private AutoService bmwAutoService;

    @Inject
    @Named("hondaAutoService")
    private AutoService hondaAutoService;

    @Test
    public void bmwAutoServiceTest() {
        Assert.assertEquals("You chose BMW auto service", bmwAutoService.getService());
    }

    @Test
    public void hondaAutoServiceTest() {
        Assert.assertEquals("You chose Honda auto service", hondaAutoService.getService());
    }
}

Notes

  • @RunWith(Arquillian.class) provides to run our test class with Arquillian features.
  • We have to create a public static method to bootstrap a virtual context for our beans with @Deployment annotation. This method returns a ShrinkWrap archive.
  • The classes which we are going to inject and test should be added into archive. On the other hand, we can add package(s) instead of adding classes.
  • As specified in this article we have to create a beans.xml file to use CDI beans. So, the location of the beans.xml file will be different due to our project type.

Finally, we will notice that our tests will run without any issues.