爪哇 - 合同测试(Java - contract tests)

2019-07-30 02:09发布

我想写合同测试设置一些广泛使用的接口:

沿着线:

public abstract class MyInterfaceContractTest extends TestCase {

  private MyInterface _toTest;

  public void setUp(){
    _toTest = getTestableImplementation();
  }

  protected abstract MyInterface getTestableImplementation();

  public void testContract(){

  }
}

...和...

public class MyInterfaceImplementationTest extends MyInterfaceContractTest {

  protected MyInterface getTestableImplementation(){
    return new MyInterfaceImplementation(...);
  }
}

不过,我希望能够测试的多个实例MyInterfaceImplementation 。 在我的使用情况下,这是一个包含数据的集合(具有指定为每接口存取不可变对象MyInterface ),并且它可能是空的,或具有数据,或甚至大量的数据的量小。

所以,问题是,我如何测试我实现的多个实例?

此刻,我要初始化实现将其传递到抽象的合同测试。 一种方法是有多个测试类每个实现的,其中每个测试类测试一些具体的实施实例 - 但是那似乎有点冗长,难以跟踪。

FWIW,我使用JUnit 3。

Answer 1:

如果我理解正确的话你的需要,你要运行了相同的接口的多种实现同样的测试方法或方法。

我不知道如何在JUnit 3中做到这一点非常漂亮。

如果你愿意升级到JUnit 4中,这可以通过使用一个参数化测试来完成。

对于运行在接口上的两个实现一个单一的测试方法的简单的例子,你的测试代码可能是这个样子:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

import static junit.framework.Assert.assertEquals;

// Tell JUnit4 to run it as a parametrized test.
@RunWith(Parameterized.class)
public class MyInterfaceContractTest {

    private MyInterface _toTest;

    // Load the test data into your test instance via constructor
    public MyInterfaceContractTest(MyInterface impl) {
        this._toTest = impl;
    }

    // Supply the test data, in this example just the two implementations you want to test.
    @Parameterized.Parameters
    public static Collection<Object[]> generateData() {
        return Arrays.asList(new Object[]{new MyInterfaceImpl1()}, new Object[]{new MyInterfaceImpl2()});
    }

    @Test
    public void testContract(){
        // assert whatever, using your _toTest field
    }
}

运行这个测试时,JUnit会运行测试两次,要求在参数列表中的条目连续的构造。

如果你有更复杂的东西,比如对不同实现不同的期望,数据生成可以返回包含多个元素的对象数组列表,然后构造将采取相应的多个参数。

如果您需要重新初始化测试方法之间的测试对象,你可能也想使用我所描述的把戏此相关的问题 。

我相信类似的事情都是可能的TestNG的 ,这可能是你的升级路径的另一种选择。



Answer 2:

一般的方法是使用抽象类的“可验证”的子类来测试抽象类的所有功能于一体的测试。 然后写在具体的类中实现公正的方法来定义每个具体实施测试/单独的测试(不复试的具体类的功能)。



文章来源: Java - contract tests