I have an abstract testcase "AbstractATest" for an interface "A". It has several test methods (@Test) and one abstract method:
protected abstract A unit();
which provides the unit under testing. No i have multiple implementations of "A", e.g. "DefaultA", "ConcurrentA", etc.
My problem: The testcase is huge (~1500 loc) and it's growing. So i wanted to split it into multiple testcases. How can organize/structure this in Junit 4 without the need to have a concrete testcase for every implementation and abstract testcase.
I want e.g. "AInitializeTest", "AExectueTest" and "AStopTest". Each being abstract and containing multiple tests. But开发者_JS百科 for my concrete "ConcurrentA", i only want to have one concrete testcase "ConcurrentATest".
I hope my "problem" is clear.
EDIT
Looks like my description was not that clear. Is it possible to pass a reference to a test? I know parameterized tests, but these require static methods, which is not applicable to my setup. Subclasses of an abstract testcase decide about the parameter.Why not let each concrete test case initialise a concrete instance for test via a method called via @Before
. i.e. you initialise a new instance of the concrete instance prior to each test. The abstract test class can then provide tests working off this instance (referenced via a protected field in the abstract class).
So you'll have one test class per concrete instance, and those will simply provide a new instance to test against. The abstract test class that these derive from provide all the tests. When you create a new concrete type, you simply need a new concrete test class to instantiate an instance of that class.
You can introduce a paramter to the test methods and use one @DataProvider creating instances of all classes to be tested. Ok, all in one test.
I don't know if you've solved this already, but I'd suggest that you keep your one abstract test, but externalize the implementations of the methods in that abstract class.
For example, create a class with your Initialize tests
public class InitializeTester {
protected static void testInitializeA(A unit) {
...
assertSomething ...
}
protected static void testInitializeB(A unit) {
...
assertSomething ...
}
}
A Class with your Execute Tests:
public class ExecuteTester {
protected static void testExecuteA(A unit) {
...
assertSomething ...
}
protected static void testExecuteB(A unit) {
...
assertSomething ...
}
}
Then your actual abstract Tester:
public abstract class ATester {
@Test
public void testInitializA() {
InitializeTester.testInitializeA(unit());
}
@Test
public void testInitializB() {
InitializeTester.testInitializeB(unit());
}
@Test
public void testExecuteA() {
testExecuteTester.testExecuteA(unit());
}
@Test
public void testExecuteB() {
testExecuteTester.testExecuteB(unit());
}
abstract protected A unit();
}
You may end up with the abstract test class having a lot of methods, but they'll all be very short, as they pass control to your Tester classes.
精彩评论