
[id='testing-in-a-container_{context}']
= Testing in a container

Using Arquillian, you have the capability of injecting unit tests into a
running application. This allows you to verify your application is behaving
correctly. There is an adapter for {Thorntail} that makes Arquillian-based
testing work well with {Thorntail}{ndash}based applications.

[discrete]
== Prerequisites

* A Maven-based application with a `pom.xml` file.

[discrete]
== Procedure

. Include the {Thorntail} BOM as described in xref:using-a-bom_{context}[]:
+
[source,xml]
----
<dependencyManagement>
  <dependencies>
include::pom.xml[tag=bom,indent=4]
  </dependencies>
</dependencyManagement>
----

. Reference the `io.thorntail:arquillian` artifact in your `pom.xml` file
with the `<scope>` set to `test`:
+
[source,xml]
----
<dependencies>
include::pom.xml[tag=arquillian,indent=2]
</dependencies>
----

. Create your Application.
+
Write your application as you normally would; use any default
`project-defaults.yml` files you need to configure it.
+
[source,yml]
----
include::src/main/resources/project-defaults.yml[]
----

. Create a test class.
+
NOTE: Creating an Arquillian test before {Thorntail} existed usually involved
programatically creating `Archive` due to the fact that applications
were larger, and the aim was to test a single component in isolation.
+
[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=classdef,indent=0]
----

. Create a deployment.
+
--
In the context of microservices, the entire application represents one small
microservice component.

Use the `@DefaultDeployment` annotation to automatically
create the deployment of the entire application. The `@DefaultDeployment`
annotation defaults to creating a `.war` file, which is not applicable in
this case because Undertow is not involved in this process.

Apply the `@DefaultDeployment` annotation at the class level of a JUnit test,
along with the `@RunWith(Arquillian.class)` annotation:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=prolog,indent=0]
----

Using the `@DefaultDeployment` annotation provided by Arquillian integration
with {Thorntail} means you should _not_ use the Arquillian `@Deployment`
annotation on static methods that return an `Archive`.

The `@DefaultDeployment` annotation inspects the package of the test:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=package,indent=0]
----

From the package, it uses heuristics to include all of your other application
classes in the same package or deeper in the Java packaging hierarchy.

Even though using the `@DefaultDeployment` annotation allows you to write tests
that only create a _default deployment_ for sub-packages of your application,
it also prevents you from placing tests in an unrelated package, for example:

[source,java]
----
package org.mycorp.myapp.test;
----
--

. Write your test code.
+
--
Write an Arquillian-type of test as you normally would, including using
Arquillian facilities to gain access to internal running components.

In the example below, Arquillian is used to inject the `InitialContext` of the
running application into an instance member of the test case:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=arquillian-resource,indent=0]
----

That means the test method itself can use that `InitialContext` to ensure the
Datasource you configured using `project-defaults.yml` is live and available:

[source,java]
----
include::src/test/java/org/wildfly/swarm/howto/incontainer/InContainerTest.java[tag=test,indent=0]
----
--

. Run the tests.
+
Because Arquillian provides an integration with JUnit, you can execute your
test classes using Maven or your IDE:
+
[source,shell]
----
$ mvn install
----
+
NOTE: In many IDEs, execute a test class by right-clicking it and selecting `Run`.

