There is no doubt that unit/component testing is essential for most of the applications. Sometimes the component under the test needs to communicate with other components. This is where we usually reach for mocking frameworks. And if it's not sufficient (or too complicated) there are still integration tests. Integration tests are usually more time and resource-consuming though. And for CDI components mocks might very oftten become too complex. Not to mention the services provided by the container (interceptors, decorators, events, programmatic lookup, etc.) are hard to mock (if at all). That's the reason why Arquillian has an embedded Weld container. Recently, the first beta version (beta but stable and ready to use) of Weld JUnit extensions was released. Well, it's just another tool for testing CDI components. So how does it differ from other tools such as Arquillian, DeltaSpike Test Control and CDI-Unit? Well, it's really simple, easy to use, fast and it leverages the powerful Weld SE Bootstrap API.

 

Get Started

Just add one dependency to your pom.xml:

 

<dependency>
  <groupId>org.jboss.weld</groupId>
  <artifactId>weld-junit4</artifactId>
  <version>${version.weld-junit}</version>
</dependency>

 

NOTE: At the time I wrote this article the artifact was only available in JBoss Maven repository. However, it should reach the Maven Central sooner or later.

 

And then add WeldInitiator test rule to your test:

 

import static org.junit.Assert.assertEquals;
import org.junit.Rule;
import org.junit.Test;

public class SimpleTest {

    @Rule
    public WeldInitiator weld = WeldInitiator.of(Foo.class);

    @Test
    public void testFoo() {
        // Note that Weld container is started automatically
        // WeldInitiator can be used to perform programmatic lookup of beans
        assertEquals("baz", weld.select(Foo.class).get().getBaz());
        // WeldInitiator can be used to fire a CDI event
        weld.event().select(Baz.class).fire(new Baz());
    }

}

 

org.jboss.weld.junit.WeldInitiator is a test rule (JUnit 4.9+) which starts/stops a Weld container per test method execution. The container is configured through the Weld SE Bootstrap API, i.e. a provided org.jboss.weld.environment.se.Weld instance. A convenient static method WeldInitiator.of(Class<?>...) is also provided - in this case, the container is optimized for testing purposes (with automatic discovery and concurrent deployment disabled) and only the given bean classes are considered. WeldInitiator also implements javax.enterprise.inject.Instance and therefore might be used to perform programmatic lookup of bean instances. It's also possible to use the convenient static method WeldInitiator.ofTestPackage() - the container is optimized for testing purposes and all the classes from the test class package are added. Sometimes, the programmatic lookup can imply unnecessary overhead, e.g. an annotation literal must be used for parameterized types and qualifiers with members. WeldInitiator.inject(Object) instructs the rule to inject the given non-contextual instance once the container is started, i.e. during each test method execution:

 

public class InjectTest {

    @Rule
    public WeldInitiator weld = WeldInitiator.of(Foo.class).inject(this);

    // Gets injected by WeldInitiator when testFoo() is about to be run
    @Inject
    @MyQualifier
    Foo foo;

    @Test
    public void testFoo() {
        assertEquals(42, foo.getValue());
    }

}

 

And that's basically all. The Weld SE Bootstrap API is really powerful and allows to minimize the set of classes to be processed by the CDI container. As a result, the tests are fast and lightweight!