简体   繁体   English

我是否需要测试接口的每个实现来测试接口?

[英]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 . 假设我有一个Destroyer接口和一个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. 如果我写另一个实现类EpicDestroyer我现在觉得我必须测试它。

So, do I write two test classes DestroyerImplTest and EpicDestroyerTest that both test the same Destroyer interface with different implementations? 那么,我是否编写了两个测试类DestroyerImplTestEpicDestroyerTest ,它们都使用不同的实现来测试相同的Destroyer接口? 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. 包含测试接口规范的测试用例 - 在本例java.util.List 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? 那么,我是否编写了两个测试类DestroyerImplTest和EpicDestroyerTest,它们都使用不同的实现来测试相同的Destroyer接口?

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. 当然,您可能希望测试每个实现,但是为了测试实现类,而不是接口本身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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