Reputation: 33
Initially, I wrote a class (lets call it RangeSet
) that operated on an ArrayList
of intervals (the interval class defined by me as two Long values). The list was a collection of intervals, there was a void add(Range range)
method which checked whether there was an overlap, overwriting, containment or adjacency with intervals already on the list. The point was to hold the list of non-overlaping intervals.
I designed and wrote extensive tests for that class, checking the wide variety of cases that may occur. It's a lot of code is what I'm saying.
Now it turns out that (for whatever reason) I had to split that class into two seperate classes - RangeSet
will be an abstract class with a couple of useful methods and inherited from it - ArrayRangeSet
(holding the collection of intervals in ArrayList
) and TreeRangeSet
(holding the collection of intervals in a TreeSet
). The implementation of add(Range range)
method differs a lot between those two.
How shall I inherit tests to avoid redundancy in defining test data?
An example test looks like this:
@Test
void testCase4(){
RangeSet set = new RangeSet();
Range r1 = new Range(4, 5);
Range r2 = new Range(13, 15);
Range r3 = new Range(19, 22);
set.add(r1);
set.add(r2);
set.add(r3);
Range testRange = new Range(11,100);
set.add(testRange);
assertEquals(2,set.iterator().size());
assertEquals(new Range(4,5),set.iterator().getAt(0));
assertEquals(new Range(11,100),set.iterator().getAt(1));
}
I dont know whether I'm being clear: There's a lot of test data defining and tests for those two classes would look the same. How do I solve that?
EDIT: Is there a way to pass those assert statements to inherited test classes? Afterall, those add
methods are supposed to achieve the same goal, albeit by different operations.
Upvotes: 3
Views: 248
Reputation: 330
I would write a test class for RangeSet
, that provides the test data and let the tests of ArrayRangeSet
and TreeRangeSet
inherit from it. If you provide a mechanism to create instances of ArrayRangeSet
and TreeRangeSet
in the base test (e.g. an abstract "factory" method), you can put the tests of all methods that are supposed to have the same behavior in both classes into the base test. The test classes ArrayRangeSet
and TreeRangeSet
contain only tests of "specific" methods.
Upvotes: 0
Reputation: 39887
You can use a fixture method, like JUnit @Before
. Or you can keep that in a separate fixture class. Or perhaps you may like to keep it in a property file, if it suits there. I mean there are multiple options.
That sort of fixture doesn't sound like a parent to me. I mean there is not is a
relationship between fixture and test class. Btw, there is no harm to have base class to handle commonality between two test classes. If you decide on the base class, you can have a setup
, or say /@Before
, method there, which prepares the data in a single place.
Upvotes: 1
Reputation: 771
Put the shared test data into an immutable and constant class like RangeSetTestData
holding everything that is needed for the tests to run. Implement three tests against RangeSet
, TreeRangeSet
and ArrayRangeSet
, that test the functionality based on the constant test data.
Edit: That way you do not have to cope with serialization and deserialization of any property files / test resources, and the constant test data class is very well maintainable.
Upvotes: 0