This module provides the ability to bootstrap Isis within a JUnit testing framework, using any object store. This is done using a JUnit rule.
In addition, the UI can be integration tested by "wrapping" each domain object in a proxy. This proxy ensures that the "see it/use it/do it" rules (ie to hide, disable, or validate) are enforced. The wrapping is performed using the WrapperFactory, part of the isis-core-wrapper module.
To use, update the pom.xml:
<dependency>
<groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-integtestsupport</artifactId>
</dependency>
<dependency>
<groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-wrapper</artifactId>
</dependency>
A full example is provided in the quickstart archetype. But to briefly explain; the recommended approach is to create an abstract class for all your integration tests. Here is the one from the quickstart archetype:
public abstract class AbstractIntegTest {
protected ToDoItems toDoItems;
protected WrapperFactory wrapperFactory;
protected DomainObjectContainer container;
@Rule
public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
@Rule
public IsisSystemForTestRule bootstrapIsis = new IsisSystemForTestRule();
@Rule
public ExpectedException expectedExceptions = ExpectedException.none();
/**
* Same running system returned for all tests, set up with {@link ToDoItemsFixture}.
*
* <p>
* The database is NOT reset between tests.
*/
public IsisSystemForTest getIsft() {
return bootstrapIsis.getIsisSystemForTest();
}
@Before
public void init() {
toDoItems = getIsft().getService(ToDoItemsJdo.class);
wrapperFactory = getIsft().getService(WrapperFactoryDefault.class);
container = getIsft().container;
}
protected <T> T wrap(T obj) {
return wrapperFactory.wrap(obj);
}
protected <T> T unwrap(T obj) {
return wrapperFactory.unwrap(obj);
}
// other boilerplate omitted
}
Each of the integration tests then inherit from this abstract class. For example, here's a test of the ToDoItem's completed() action:
public class ToDoItem_completed extends AbstractIntegTest {
private ToDoItem toDoItem;
private boolean isComplete;
@Before
public void setUp() throws Exception {
// given
final List<ToDoItem> all = wrap(toDoItems).notYetComplete();
toDoItem = wrap(all.get(0));
// to reset after
isComplete = toDoItem.isComplete();
}
@After
public void tearDown() throws Exception {
unwrap(toDoItem).setComplete(isComplete);
}
@Test
public void happyCase() throws Exception {
// given
assertThat(toDoItem.isComplete(), is(false));
// when
toDoItem.completed();
// then
assertThat(toDoItem.isComplete(), is(true));
}
@Test
public void cannotCompleteIfAlreadyCompleted() throws Exception {
// given
unwrap(toDoItem).setComplete(true);
// when, then should fail
expectedExceptions.expectMessage("Already completed");
toDoItem.completed();
}
@Test
public void cannotSetPropertyDirectly() throws Exception {
// given
// when, then should fail
expectedExceptions.expectMessage("Always disabled");
toDoItem.setComplete(true);
}
}
Note that when the ToDoItem is wrapped, it is not possible to call setComplete() directly on the object; but when it is unwrapped then this call can be made as per normal.
The full source code, plus other example tests, can be found here.