TwiP provides a mechanism to extend the functionality of JUnit. It is not as powerful as the RunWith-Annotation, but you can add any number of them, and they are easier to implement.

These extensions come bundeled with TwiP:

Verify-Extension

TwiP brings an extension that allows you to collect several assertion failures in one test.

Normally JUnit stops the verification phase as soon as you hit some assert that fails. With the verifyThat method, the failure is simply recorded and verification continues. This extension then checks all failures after the method returns, throwing one single exception for JUnit to display. If an exception occurs after a verification happened, then a proper description will be appended to the verification exception.

By using verifyThat your tests move from "one assert per test" closer to "single concept per test", as suggested by Uncle Bob (see Robert C. Martin: Clean Code; p. 130f).

Note that you'll get a helpful exception if you happen to call verifyThat without the VerifyExtension annotation.

Usage:

import static net.sf.twip.verify.Verify.*;
import static org.hamcrest.Matchers.*;

@RunWith(TwiP.class)
public class VerifyExtensionTest {
        @Test
        public void shouldFailTwice() throws Exception {
                verifyThat(1, is(2));
                verifyThat(2, is(1));
        }
}

Mockito-Extension

This extension makes it easier to work with Mockito.

This extension does just two things: It instantiates the mock member variables of your test annotated my @Mock (the mockito one!). And it calls validateMockitoUsage() after your test. Without that, Mockito complains about an incomplete mockito call like verify(mock); only in the next test case that runs... or not at all if it is the last test.

Usage:

@RunWith(TwiP.class)
abstract public class TwipMockitoTest {
    ...
    @Mock
    private Runnable runnable;
        ...
}

JMock-Extension

This extension makes it easier to work with JMock.

You can annotate member variables of some interface type with @Mock; and TwiP automatically creates a mock for them... you don't even have to declare a mockery if the mocks will not be called. But if you do, e.g. to declare expecations, of course TwiP uses that to create the mocks; if you declare only the mockery field, without assigning a value, TwiP even creates the mockery and assigns it.

And TwiP checks the mockery when the test run is finished, just as the JMock Runner does, of course.

If you think this is still too much boilerplate code, just extend the TwiPjMockTest class instead, which is defined as:

@RunWith(TwiP.class)
abstract public class TwipJMockTest {
        ...
}

Writing Extensions

to be documented; see the existing extensions as examples

Note that you can either annotate your test class explicitly with the TwipExtensions you want to use:

@RunWith(TwiP.class)
@TwipExtensions(XxxExtension.class)
public class MyTest {
        @Test
        public void shouldDoSomething() throws Exception {
                ...
        }
}

Or you can rely on the service loading mechanism to load them automatically. While the latter is more convenient, there is a possibility of tests failing silently... wich is the worst thing that can happen to a test. Depending on how an extension is used and/or written, this could not be a problem. The extensions that come with TwiP can be loaded if there is a java.util.ServiceLoader (since Java 1.6 and in the Apple VM 1.5) or sun.misc.Service (in the Sun Java VM 1.5) available. If this is not the case, tests relying on them will fail... some with a NullPointerException, others with a dedicated exception.