简体   繁体   中英

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?

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.

I never "test" an interface because there is nothing to test. The interface describe the service each implentation as to deliver, Its the contract.

So you have to test each implementation of this service to ensure everybody does the job correctly.

I wouldn't say that interfaces can be tested , because they provide abstraction and not implementation . Tests, on the other hand, need to ensure if a specific behavior is implemented (and the behavior is in the classes).

So, do I write two test classes DestroyerImplTest and EpicDestroyerTest that both test the same Destroyer interface with different implementations?

I would say, yes .

If you are testing the interface, it should be sufficient to test it with a single implementation, since the interface doesn't depend on a specific implementation.

Of course you'll probably want to test each implementation, but for the purpose of testing the implementing class, not the interface itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM