Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to test each implementation of an interface to test the interface?

Usually, I only have one implementation of an interface in my application and that first implementation is always used when writing the tests for the interface. Let's say I have an interface Destroyer and an implementation DestroyerImpl. Then I would use that class in the test:

class DestroyerTest 
{
    private Destroyer destroyer = new DestroyerImpl();

    @Test
    public void test() { ... }   
}

The class is then implicitly tested by being instantiated in the testing of the interface. If I write another implementation class EpicDestroyer I now feel like I have to test that as well.

So, do I write two test classes DestroyerImplTest and EpicDestroyerTest that both test the same Destroyer interface with different implementations? Wouldn't that be redundant? I could test each implementation in the same test suite by parameterizing it. Is this the way to do it?


1 Answers

I think there is a misconception in your thinking about testing.

There is no sense in testing an interface as it is only a specification. Only implementations can be tested. So you should test all implementations. However you may be able to derive test cases from the interface as all implementations need to adhere to the specifications in there. So even though you have completely different implementations you may share tests between those.

In my mind there should be test classes like the following:

import java.util.List;

import org.junit.Assert;
import org.junit.Test;


public abstract class AbstractModifiableListTest
{

    protected abstract <T> List<T> createListInstanceUnderTest(T... elements);

    @Test
    public void removeDecreasesSizeByOne() {
        List<String> list = this.<String>createListInstanceUnderTest("a","b","c");
        int originalSize = list.size();

        list.remove( 0 );
        int newSize = list.size();

        Assert.assertEquals( originalSize - 1, newSize );
    }
}

that contain the test cases that test the specification of the interface - java.util.List in this case. Tests for Implementations then parameterize the test case by implementing abstract methods and possibly adding implementation dependent test cases.

like image 67
SpaceTrucker Avatar answered Jan 31 '26 05:01

SpaceTrucker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!