:moduledeps: core, container-control
:moduleconf: api:org.apache.deltaspike.testcontrol.api.junit.TestBaseConfig, impl:org.apache.deltaspike.testcontrol.impl.jsf.MyFacesTestBaseConfig

= Test-Control Module

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

== Overview
The Test-Control module enables you to write CDI-based tests easily. Calls to stop and start the CDI container are built into the Test-Control API, with simplified commands for customizing the management of contexts and other aspects during testing.

== Project Setup
The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <<configure#, Configure DeltaSpike in Your Projects>>. For Maven-independent projects, see <<configure#config-maven-indep,Configure DeltaSpike in Maven-independent Projects>>.

=== 1. Declare Test-Control Module Dependencies
Add the Test-Control module to the list of dependencies in the project `pom.xml` file using this code snippet:

[source,xml]
----
<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-test-control-module-api</artifactId>
    <version>${deltaspike.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-test-control-module-impl</artifactId>
    <version>${deltaspike.version}</version>
    <scope>test</scope>
</dependency>
----

Or if you're using Gradle, add these dependencies to your `build.gradle`:

[source]
----
     testCompile 'org.apache.deltaspike.modules:deltaspike-test-control-module-impl'
     testRuntime 'org.apache.deltaspike.modules:deltaspike-test-control-module-api'
----

=== 2. Declare CDI-implementation-specific dependencies

The Test-Control module depends on the Container-Control module, which provides adapters for several major CDI implementations. Therefore, to use Test-Control, declare dependency on a CDI implementation and a corresponding Container Control implementation in the `pom.xml`.

==== OpenWebBeans

If you are using OpenWebBeans, add an OpenWebBeans implementation and the OpenWebBeans-specific Container Control module to the list of dependencies:

[source,xml]
-----------------------------------------------------
 <dependency>
     <groupId>org.apache.deltaspike.cdictrl</groupId>
     <artifactId>deltaspike-cdictrl-owb</artifactId>
     <version>${deltaspike.version}</version>
     <scope>test</scope>
 </dependency>

<dependency>
    <groupId>org.apache.openwebbeans</groupId>
    <artifactId>openwebbeans-impl</artifactId>
    <version>${owb.version}</version>
    <scope>test</scope>
</dependency>
-----------------------------------------------------

==== Weld

If you are using Weld, add a Weld implementation and the Weld-specific Container Control module to the list of dependencies:

[source,xml]
----------------------------------------------------
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-weld</artifactId>
    <version>${deltaspike.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>${weld.version}</version>
    <scope>test</scope>
</dependency>
----------------------------------------------------

==== OpenEJB

If you are using OpenWebBeans as the CDI implementation and you need to test
EJBs as well, add the OpenEJB-specific Container Control module to the list 
of dependencies instead of the OpenWebBeans-specific Container Control module:

[source,xml]
----------------------------------------------------
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-openejb</artifactId>
    <version>${deltaspike.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>openejb-core</artifactId>
    <version>${openejb.version}</version>
    <scope>test</scope>
</dependency>
----------------------------------------------------

=== 3. Complete Additional Project Configuration

Add a `beans.xml` file in the project test module (e.g. src/test/resources/META-INF/beans.xml).

== Automated Container Booting and Shutdown

=== CdiTestRunner

Start and stop the CDI container automatically per test class with CdiTestRunner, a JUnit Test-Runner. 
This also starts and stops one request and session per test-method.

.Example of CdiTestRunner Usage
[source,java]
--------------------------------------------------------
@RunWith(CdiTestRunner.class)
public class ContainerAndInjectionControl
{
    @Inject
    private ApplicationScopedBean applicationScopedBean;

    @Inject
    private SessionScopedBean sessionScopedBean;

    @Inject
    private RequestScopedBean requestScopedBean;

    //test the injected beans
}
--------------------------------------------------------

=== CdiTestSuiteRunner

Extend automated CDI container start and stop actions to whole test suites with CdiTestSuiteRunner, a JUnit Test-Suite-Runner.

.Example of CdiTestSuiteRunner Usage
[source,java]
---------------------------------------
@RunWith(CdiTestSuiteRunner.class)
@Suite.SuiteClasses({
    TestX.class,
    TestY.class
})
public class SuiteLevelContainerControl
{
}
---------------------------------------

=== Optional Shutdown Configuration

You can set `deltaspike.testcontrol.stop_container` to `false` (via the standard DeltaSpike config), resulting in the CDI Container being started just once for all tests.

== Test Customization

=== @TestControl

Customize the default behavior of CdiTestRunner with @TestControl. In the following
case only one session for all test-methods (of the test-class) will be
created.

.Example of @TestControl Usage
[source,java]
-----------------------------------------------
@RunWith(CdiTestRunner.class)
@TestControl(startScopes = SessionScoped.class)
public class CustomizedScopeHandling
{
    //inject beans and test them
}
-----------------------------------------------

=== ProjectStage Control

Override the default ProjectStage for unit tests with `ProjectStage.UnitTest.class`.

.Example of projectStage Usage
[source,java]
---------------------------------------------------------------
@RunWith(CdiTestRunner.class)
@TestControl(projectStage = CustomTestStage.class)
public class TestStageControl
{
    //tests here will see ProjectStage CustomTestStage.class

    @Test
    @TestControl(projectStage = ProjectStage.Development.class)
    public void checkDevEnv()
    {
    }

    //tests here will see ProjectStage CustomTestStage.class
}
---------------------------------------------------------------

== Optional Configuration

From DeltaSpike 1.2, it is possible to provide a configuration for the underlying test-container.
However, currently only the adapter for OpenEJB embedded (available in CDI-Control) supports it out-of-the-box.
To pass properties to the underlying test-container,
you have to add `/META-INF/apache-deltaspike_test-container.properties`
to the resources-directory of your test-classpath.
The content of the file are key/value pairs which get passed to the container.
Therefore, it is a configuration which is not used by DeltaSpike itself
(it is just forwarded (as it is) to the underlying test-container).

=== Reconfigure the config-file Name or Location

If you would like to point to an existing config-file, you have to add for example:

[source,Properties]
---------------------------------------------------------------
deltaspike.testcontrol.test-container.config-file=META-INF/existingConfig.properties
---------------------------------------------------------------

to `/META-INF/apache-deltaspike.properties`.

If you would like to do it per ProjectStage, you can use for example:

[source,Properties]
---------------------------------------------------------------
deltaspike.testcontrol.test-container.config-file.UnitTest=META-INF/unit-test/existingConfig.properties
---------------------------------------------------------------


== Optional Integrations

=== Mock Frameworks

From DeltaSpike 1.0, it is possible to mock CDI-Beans. Usually @Exclude (+
ProjectStage) is enough, however, for some cases mocked beans might be
easier. Therefore it is possible to create (mock-)instances manually or
via a mocking framework and add them, for example, via `DynamicMockManager`.

**Attention:** Mocking CDI beans is not supported for every feature of CDI and/or
every implementation version. For example, we can not mock intercepted CDI beans and
with some implementations mocking specialized beans fails.
Usually all features are active by default, however,
due to those reasons we deactivated this feature by default.
You can enable it by adding

`deltaspike.testcontrol.mock-support.allow_mocked_beans=true`
and/or
`deltaspike.testcontrol.mock-support.allow_mocked_producers=true`

to `/META-INF/apache-deltaspike.properties` in your test-folder.

If you need dependency-injection in the mocked instances, you can use
`BeanProvider.injectFields(myMockedBean);`.

[source,java]
-------------------------------------------------------------
@RunWith(CdiTestRunner.class)
public class MockedRequestScopedBeanTest
{
    @Inject
    private RequestScopedBean requestScopedBean;

    @Inject
    private DynamicMockManager mockManager;

    @Test
    public void manualMock()
    {
        mockManager.addMock(new RequestScopedBean() {
            @Override
            public int getCount()
            {
                return 7;
            }
        });

        Assert.assertEquals(7, requestScopedBean.getCount());
        requestScopedBean.increaseCount();
        Assert.assertEquals(7, requestScopedBean.getCount());
    }
}

@RequestScoped
public class RequestScopedBean
{
    private int count = 0;

    public int getCount()
    {
        return count;
    }

    public void increaseCount()
    {
        this.count++;
    }
}
-------------------------------------------------------------

Using a mocking framework makes no difference for adding the mock.

.Example via Mockito
[source,java]
----------------------------------------------------------------------------------
@RunWith(CdiTestRunner.class)
public class MockitoMockedRequestScopedBeanTest
{
    @Inject
    private RequestScopedBean requestScopedBean;

    @Inject
    private DynamicMockManager mockManager;

    @Test
    public void mockitoMockAsCdiBean()
    {
        RequestScopedBean mockedRequestScopedBean = mock(RequestScopedBean.class);
        when(mockedRequestScopedBean.getCount()).thenReturn(7);
        mockManager.addMock(mockedRequestScopedBean);

        Assert.assertEquals(7, requestScopedBean.getCount());
        requestScopedBean.increaseCount();
        Assert.assertEquals(7, requestScopedBean.getCount());
    }
}
----------------------------------------------------------------------------------

Since CDI implementations like OpenWebBeans use a lot of optimizations,
it is required to handle mocks for application-scoped beans differently, for example:

[source,java]
--------------------------------------------------------------------------------------------------------------------------
@RunWith(CdiTestRunner.class)
public class MockedApplicationScopedBeanTest
{
    @Inject
    private ApplicationScopedBean applicationScopedBean;

    @BeforeClass
    public static void init()
    {
        ApplicationMockManager applicationMockManager = BeanProvider.getContextualReference(ApplicationMockManager.class);
        applicationMockManager.addMock(new MockedApplicationScopedBean());
    }

    @Test
    public void manualMock()
    {
        Assert.assertEquals(14, applicationScopedBean.getCount());
        applicationScopedBean.increaseCount();
        Assert.assertEquals(14, applicationScopedBean.getCount());
    }
}

@ApplicationScoped
public class ApplicationScopedBean
{
    private int count = 0;

    public int getCount()
    {
        return count;
    }

    public void increaseCount()
    {
        this.count++;
    }
}

@Typed() //exclude it for the cdi type-check
public class MockedApplicationScopedBean extends ApplicationScopedBean
{
    @Override
    public int getCount()
    {
        return 14;
    }
}
--------------------------------------------------------------------------------------------------------------------------

However, `ApplicationMockManager` can be used for adding all mocks, if
they should be active for the lifetime of the CDI-container.

It is also possible to mock qualified beans. Just add the
literal-instance(s) as additional parameter(s), for example:

[source,java]
-------------------------------------------------------------
@RunWith(CdiTestRunner.class)
public class MockedQualifiedBeanTest
{
    @Inject
    @MyQualifier
    private QualifiedBean qualifiedBean;

    @Inject
    private DynamicMockManager mockManager;

    @Test
    public void manualMockWithQualifier()
    {
        mockManager.addMock(new QualifiedBean() {
            @Override
            public int getCount()
            {
                return 21;
            }
        }, AnnotationInstanceProvider.of(MyQualifier.class));

        Assert.assertEquals(21, qualifiedBean.getCount());
        qualifiedBean.increaseCount();
        Assert.assertEquals(21, qualifiedBean.getCount());
    }
}
-------------------------------------------------------------

In some cases it is necessary to use `@javax.enterprise.inject.Typed`.
Mocking such typed beans can result in an
`AmbiguousResolutionException`. Therefore it is necessary to exclude the
mocked implementation via `@Exclude` or `@Typed()` (or a parametrized
constructor) and specify the target-type via `@TypedMock`.

=== JSF (via MyFaces-Test)

add one of

* org.apache.deltaspike.testcontrol.impl.jsf.MockedJsf2TestContainer
* org.apache.deltaspike.testcontrol.impl.jsf.MockedJsfTestContainerAdapter
* org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerAdapter
* org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerPerTestMethodAdapter

as content to

`/META-INF/services/org.apache.deltaspike.testcontrol.spi.ExternalContainer`

(in your config-folder for tests, e.g. test/resources)

== Using jersey-test with test-control

Jersey-test starts jetty which answers requests in a separated thread. Since ds test-control just handles the thread of the test itself, it's needed to integrate jetty and jersey with the cdi-container. Usually that's done via a ServletRequestListener - the following part describes an alternative approach for jersey-test:

[source,java]
-------------------------------------------------------------------------------------------
//use: -Djersey.config.test.container.factory=custom.CdiAwareJettyTestContainerFactory

@RunWith(CdiTestRunner.class)
public class SimpleCdiAndJaxRsTest extends JerseyTest
{
  //...
}
-------------------------------------------------------------------------------------------
or
[source,java]
-------------------------------------------------------------------------------------------
public class CdiAwareJerseyTest extends JerseyTest
{
    static
    {
        System.setProperty("jersey.config.test.container.factory", CdiAwareJettyTestContainerFactory.class.getName());
    }
}

@RunWith(CdiTestRunner.class)
public class SimpleCdiAndJaxRsTest extends CdiAwareJerseyTest
{
    //...
}
-------------------------------------------------------------------------------------------
[source,java]
-------------------------------------------------------------------------------------------
public class CdiAwareJettyTestContainerFactory implements TestContainerFactory
{
    @Override
    public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException
    {
        return new CdiAwareJettyTestContainer(baseUri, context);
    }
}
-------------------------------------------------------------------------------------------

CdiAwareJettyTestContainer is a copy of JettyTestContainerFactory.JettyTestContainer but with

[source,java]
-------------------------------------------------------------------------------------------
HandlerWrapper cdiHandlerWrapper = new CdiAwareHandlerWrapper();
cdiHandlerWrapper.setHandler(this.server.getHandler());
this.server.setHandler(cdiHandlerWrapper);
-------------------------------------------------------------------------------------------
after the line with JettyHttpContainerFactory#createServer
[source,java]
-------------------------------------------------------------------------------------------
//activate the request-context e.g. via:
public class CdiAwareHandlerWrapper extends HandlerWrapper
{
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();

        try
        {
            cdiContainer.getContextControl().startContext(RequestScoped.class);
            super.handle(target, baseRequest, request, response);
        }
        finally
        {
            cdiContainer.getContextControl().stopContext(RequestScoped.class);
        }
    }
}
-------------------------------------------------------------------------------------------

== Mixed Tests

Usually you should have one kind of tests per test-module. However, if
you need to add, for example, a test without an external-container to your
test-module which uses external-containers, you can annotate your test
with:

[source,java]
---------------------------------------------
@RunWith(CdiTestRunner.class)
@TestControl(startExternalContainers = false)
public class JsfContainerTest
{
    //...
}
---------------------------------------------


== Known Restrictions

=== Liquibase

Liquibase invokes `#toString` in a `AfterDeploymentValidation` observer.
*that is not portable* and therefore you have to deactivate the
mocking-support via:

[source,java]
----------------------------------------------------------------------------------------------------------
public class LiquibaseAwareClassDeactivator implements ClassDeactivator {
    @Override
    public Boolean isActivated(Class<? extends Deactivatable> targetClass) {
        return !"org.apache.deltaspike.testcontrol.impl.mock.MockExtension".equals(targetClass.getName());
    }
}
----------------------------------------------------------------------------------------------------------

and add `LiquibaseAwareClassDeactivator` to `/META-INF/apache-deltaspike.properties`, for example:

---------------------------------------------------------------------------------------------------
org.apache.deltaspike.core.spi.activation.ClassDeactivator=myPackage.LiquibaseAwareClassDeactivator
---------------------------------------------------------------------------------------------------

Further details are available at deactivatable.

=== Gradle

Gradle by default does not put resources and compiled sources in to the same directory.
When running a test using Gradle, this means your classes will not be in bean archives as
defined by the CDI spec.  To work around this, you need to set your main and test directories
for resources to point to where the compiled code lives.  This is an example of how to do that:

[source,groovy]
----------------------------------------------------------------------------------------------------------
sourceSets {
    main {
        output.resourcesDir = output.classesDir
    }
    test {
        output.resourcesDir = output.classesDir
    }
}

// ensure you're excluding duplicates

jar {
    duplicatesStrategy = 'exclude'
}
----------------------------------------------------------------------------------------------------------

== SPI

=== MockFilter

Please make sure that you are aware of <<__MockFrameworks, Integration of Mock Frameworks>> before you continue with this section.

If you would like to exclude some parts of your application- and/or test-code
so that they aren’t eligible for the mocking mechanism,
you can provide an own implementation of `org.apache.deltaspike.testcontrol.spi.mock.MockFilter` and
register it in `/META-INF/services/org.apache.deltaspike.testcontrol.spi.mock.MockFilter`.

That's quite special and you need to know the CDI-SPI a bit.
To get an idea about the required steps, you can have a look at the default implementation used by DeltaSpike-Test itself.

Such a filter is also needed in case you would like to customize DeltaSpike-Test.
For example to provide an `@Alternative` implementation for DynamicMockManager,
you need to implement `org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager`, annotate it with `@Alternative`,
ensure that you keep the type-information with `@Typed`,
configure the alternative bean in `/META-INF/beans.xml` (in the test-classpath) and
provide a custom `MockFilter` (as described above) which excludes the custom mock-manager.
(Otherwise DeltaSpike-Test will try to mock the custom mock-manager.)

=== ExternalContainer

org.apache.deltaspike.testcontrol.spi.ExternalContainer allows to
integrate containers which get started after the CDI container.
Currently DeltaSpike provides:

* MockedJsf2TestContainer (integration with MyFaces-Test)

[TODO]
