我想写合同测试设置一些广泛使用的接口:
沿着线:
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。
如果我理解正确的话你的需要,你要运行了相同的接口的多种实现同样的测试方法或方法。
我不知道如何在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的 ,这可能是你的升级路径的另一种选择。
一般的方法是使用抽象类的“可验证”的子类来测试抽象类的所有功能于一体的测试。 然后写在具体的类中实现公正的方法来定义每个具体实施测试/单独的测试(不复试的具体类的功能)。