blob: 940a8734a67e18e2aa35373ae528aed73ba6b62f [file] [log] [blame]
= JUnit 5: Application Composer
:index-group: Testing Techniques
:jbake-type: page
:jbake-status: published
The `org.apache.openejb.junit5.ApplicationComposerExtension` is a **JUnit 5 extension** internally re-using `ApplicationComposers`, which has been used in the JUnit test runner ( `ApplicationComposer`) for testing OpenEJB in recent years. It involves no classpath scanning at all. If you want something to be in the app, you must build it directly in your testcase.
With the `RunWithApplicationComposer` you can do identical testing that OpenEJB uses internally, but with limited dependency on OpenEJB itself.
The main dependency is:
[source,xml]
----
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>openejb-junit5</artifactId>
<version>${openejb.version}</version>
</dependency>
----
Make sure to use a maven surefire version greater or equal to `3.0.0-M5` and add the required dependencies for JUnit 5.
== Composing an Application
The main difference to the embedded `EJBContainer` API is building the application in the test code. This is done with one or more methods in the test case annotated
with `org.apache.openejb.testing.Module` using the following format:
[source,java]
----
@Module
public <return-value> <module-name>() {
----
Where **module-name** is the name you wish to use for that module and **return-value** can be any one of the following:
- java.lang.Class
- java.lang.Class[]
- org.apache.openejb.jee.EjbJar
- org.apache.openejb.jee.EnterpriseBean
- org.apache.openejb.jee.Application
- org.apache.openejb.jee.Connector
- org.apache.openejb.jee.Beans
- org.apache.openejb.jee.jpa.unit.Persistence
- org.apache.openejb.jee.jpa.unit.PersistenceUnit
== Example
Used in an actual testcase, that might look like so:
[source,java,numbered]
----
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.StatefulBean;
import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
import org.apache.openejb.junit5.RunWithApplicationComposer;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.Module;
import org.junit.jupiter.api.Test;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;
import java.util.List;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertEquals;
@RunWithApplicationComposer
public class MoviesTest {
@EJB
private Movies movies;
@Resource
private UserTransaction userTransaction;
@PersistenceContext
private EntityManager entityManager;
@Module
public PersistenceUnit persistence() {
PersistenceUnit unit = new PersistenceUnit("movie-unit");
unit.setJtaDataSource("movieDatabase");
unit.setNonJtaDataSource("movieDatabaseUnmanaged");
unit.getClazz().add(Movie.class.getName());
unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
return unit;
}
@Module
public EjbJar beans() {
EjbJar ejbJar = new EjbJar("movie-beans");
ejbJar.addEnterpriseBean(new StatefulBean(MoviesImpl.class));
return ejbJar;
}
@Configuration
public Properties config() throws Exception {
Properties p = new Properties();
p.put("movieDatabase", "new://Resource?type=DataSource");
p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
return p;
}
@Test
public void test() throws Exception {
userTransaction.begin();
try {
entityManager.persist(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
entityManager.persist(new Movie("Joel Coen", "The Big Lebowski", 1998));
List<Movie> list = movies.getMovies();
assertEquals(3, list.size(), "List.size()");
for (Movie movie : list) {
movies.deleteMovie(movie);
}
assertEquals(0, movies.getMovies().size(), "Movies.getMovies()");
} finally {
userTransaction.commit();
}
}
}
----