I have been setting up some contract JUnit 4 tests (following advice in answer to this question) - e.g. if I have an interface (I've included generics in the example, since I'm using them in my project) - but, this is a significantly simplified example:
public interface MyInterface<T> {
public T myMethod();
}
I can create an abstract contract test - e.g.:
public abstract class AbstractMyInterfaceTest<T> {
private final MyInterface<T> _impl;
// plus, store stuff to test against;
public AbstractMyInterfaceTest(MyInterface<T> impl, ... stuff to test against){
_impl = impl;
// stuff to test against...
}
@Test
public void testMyMethod(){
// test some stuff...
}
}
...and extend this abstract test class for each implementation (which I am running with @RunWith(Parameterized.class)
). I'm also passing some variables to test the implementation of the interface against into the abstract test class.
However, in actuality, some interfaces return objects that are implementations of other interfaces, and I would like to be able to test this implementation using the abstract contract class for that interface (...and against the relevant variables). For example, a method in MyInterface
might return an Iterator - which is an interface. I have a separate AbstractIteratorTest
, which runs a contract test for Iterator against a set of values, and I want to check that the Iterator
returned by the implementations of MyInterface
passes the contract tests in AbstractIteratorTest
with the expected set of values.
At the moment, I'm adding the following to the abstract test classes:
// N.b. not setting @Test - so doesn't run all tests twice...
public void runTests(){
testMyMethod();
// etc.
}
However, this doesn't run each test independently (e.g. running setUp()
before each test method), so there are problems if those contract tests expect the implementation to be in a particular state for each test. (A specific example would be testing implementations of the Iterator
interface, where each test method can change the state of the tested Iterator
)
Is there was a better way of doing this, perhaps making use of features in JUnit 4?
I've seen stuff about the @RunWith(Suite.class)
annotation, but that seems to be about running multiple test classes from a single test class, and doesn't allow you to pass variables into the different test classes that are being run. There may be a way to use this Suite
to solve my problem, but I'm not sure what it is...