5

Consider the following concrete scenario: Someone has created a lot of tests that fully test the functionality to which a class implementing Collection<E> must adhere. How is it then possibly to use that test class (in some way) to test concrete implementations of Collection<E>?

By example:

public class CollectionTest {
    //lots of tests here
}

public class ACollection<E> implements Collection<E> {
    //implementation and custom methods
}

public class BCollection<E> implements Collection<E> {
    //implementation and other custom methods
}

How should I then write the test classes such that least code duplication occurs?

public class ACollectionTest {
    //tests for Collection<E>, preferably not duplicated
    //tests for custom methods
}

public class BCollectionTest {
    //tests for Collection<E>, preferably not duplicated
    //tests for other custom methods
}

In other words, is it possible to "extend CollectionTest", but have its tests run on an instance of ACollectionTest or BCollectionTest (or more)? Note that the methods are still accessible once you use ACollection<E> as Collection<E> for example.

skiwi
  • 66,971
  • 31
  • 131
  • 216
  • In guava, exists a base abstract test for the InmutableSet (for example) with a bunch of methods to obtaint the colleciton, see [the abstract](https://code.google.com/p/guava-libraries/source/browse/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java) and the implementations [here](https://code.google.com/p/guava-libraries/source/browse/guava-tests/test/com/google/common/collect/ImmutableSetTest.java) and [here](https://code.google.com/p/guava-libraries/source/browse/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java). – Arturo Volpe May 30 '14 at 17:33

1 Answers1

5

In the base class:

protected Collection<Foo> collectionUnderTest;

@Test
public void shouldDoThis() {
    // uses collectionUnderTest
}

@Test
public void shouldDoThat() {
    // uses collectionUnderTest
}

In the subclass, specific to the ACollection implementation:

@Before
public void prepare() {
    this.collectionUnderTest = new ACollection<>();
}
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I just saw this question http://stackoverflow.com/questions/6724401/how-to-write-junit-tests-for-interfaces, does that here also mean that custom rules, etc. cannot be used anymore? – skiwi May 30 '14 at 17:32
  • 2
    I don't see why they couldn't be used. But this is too vague. My advice would be: stop trying to guess or predict what will happen, what you can and can't do. Try doing it, and you'll see what happens. – JB Nizet May 30 '14 at 17:35
  • Is it possible to apply `mocking` in such example? – Leonid Dashko Feb 03 '20 at 11:16
  • @LeonidDashko Mocking is not useful here since the point is to actually call the real methods on the implementation – Captain Man Apr 15 '21 at 20:06