Embedded containers

Since unit test technology is not aware of Java EE specifics, integration tests need more sophisticated test functionality in the form of containers. There are several technologies available that start up an embedded container and make parts of the application available.

An example for this is CDI-Unit. It provides functionality to run test cases in a CDI container, further enabling developers to enhance and modify its configuration. CDI-Unit scans the dependencies of tested objects and configures them accordingly. Required mocks and test specific behavior are defined in a declarative approach. A managed bean such as the car manufacturer boundary is set up within the test case, with all required dependencies and mocks.

This approach detects configuration errors, such as missing CDI annotations. The following code snippet shows a car manufacture test, similar to the component test before, that instantiates the boundary:

import org.jglue.cdiunit.CdiRunner;

@RunWith(CdiRunner.class)
public class ManufactureCarIT {

    @Inject
    CarManufacturer carManufacturer;

    @Mock
    EntityManager entityManager;

    @Before
    public void setUp() {
        carManufacturer.entityManager = entityManager;
    }

    @Test
    public void test() {
        Specification spec = ...
        Car expected = ...

        assertThat(carManufacturer.manufactureCar(spec)).isEqualTo(expected);
        verify(entityManager).merge(expected);
    }
}

The custom JUnit runner detects beans injected into the test case and resolves them accordingly. Since CDI-Unit only supports the CDI standard and not the full Java EE API, the test explicitly mocks and sets the entity manager. All other used controls, such as the car factory, automation, and assembly line, are instantiated and injected, accordingly.

CDI-Unit tests can be enhanced to serve more sophisticated scenarios. It's possible to produce beans that are being used within the test scope.

However, this technology certainly has its limits. CDI-Unit is helpful to quickly verify configuration and collaboration of managed beans.

Another, more sophisticated technology for testing applications is Arquillian. Arquillian bundles integration test cases into deployable archives, manages enterprise containers, either embedded or remotely, and deploys, executes, and verifies the test archives. It makes it possible to enhance test cases with custom test behavior depending on the scenario.

The advantage of Arquillian is that it supports containers with full Java EE support. This enables integration tests to operate in more production-near scenarios.

The following code snippet shows a simple example of deploying the car manufacturer boundary to an embedded enterprise container managed by Arquillian:

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;

@RunWith(Arquillian.class)
public class ManufactureCarIT {

    @Inject
    CarManufacturer carManufacturer;

    @Deployment
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class)
                .addClasses(CarManufacturer.class)
                // ... add other required dependencies
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Test
    public void test() {
        Specification spec = ...
        Car expected = ...

        assertThat(carManufacturer.manufactureCar(spec)).isEqualTo(expected);
    }
}

This test case will create a dynamic web archive that ships the boundary and required delegates and deploys it into an embedded container. The test itself can inject and call methods on the specific components.

The container does not necessarily have to run in an embedded way, it can also be a managed or remote container. Containers that run for longer than just the test execution avoid the container startup time and execute tests much more quickly.

Executing these integration tests will take a comparatively long time, but operate closer to production environments. Misconfigured managed beans will be detected during development before the application is shipped. The flexibility and customization of Arquillian, by including custom bean definitions that reside in the test scope, enables pragmatic test scenarios.

However, this example only slightly touches the functionality of embedded container tests. Test frameworks such as Arquillian can be used for validating the integration of container configuration, communication, persistence, and UI. In the rest of this chapter, we will see some shortcomings of integration tests that operate on simulated or embedded environments.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.124