Java - 合同测试 [英] Java - contract tests

查看:119
本文介绍了Java - 合同测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为一些广泛使用的接口编写合同测试:

I am trying to write contract tests for some widely used interfaces:

以下行:

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 指定访问器),它可能为空,或者数量很少数据,甚至大量数据。

However, I want to be able to test multiple instances of MyInterfaceImplementation. In my use case, this is an immutable object containing a collection of data (with accessors specified as per the interface MyInterface), and it might be empty, or have a small amount of data, or even lots of data.

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

So the question is, how can I test multiple instances of my implementations?

目前,我必须初始化实现以将其传递给抽象合同测试。一种方法是为每个实现提供多个测试类,其中每个测试类测试该实现的特定实例 - 但这似乎有点庞大且难以跟踪。

At the moment, I have to initialise the implementation to pass it into the abstract contract test. One approach would be to have multiple test classes for each implementation, where each test class tests a particular instance of that implementation - but that then seems a bit voluminous and difficult to keep track of.

FWIW,我正在使用JUnit 3.

FWIW, I'm using JUnit 3.

推荐答案

如果我理解你的需要,你想要使用相同接口的多个实现运行相同的测试方法。

If I've understood your need correctly, you want to run the same test method or methods with multiple implementations of the same interface.

我不知道如何在JUnit 3中很好地完成这项工作。

I don't know how to do this very nicely in JUnit 3.

如果您愿意升级到JUnit 4,可以使用参数化测试来完成。

If you're willing to upgrade to JUnit 4, this can be done by using a parametrized test.

对于简单示例在一个接口的两个实现上运行单个测试方法,您的测试代码可能如下所示:

For the simple example of running a single test method on two implementations of an interface, your test code could look something like this:

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将运行测试两次,使用参数列表中的连续条目调用构造函数。

On running this test, JUnit will run the test twice, calling the constructor with the successive entries in the parameter list.

如果你有更复杂的事情,比如对不同实现的不同期望,数据生成可以返回包含多个元素的Object数组列表,然后构造函数会获取相应的多个参数。

If you have more complex things, like different expectations for the different implementations, the data generation could return lists of Object arrays that contain multiple elements, and the constructor would then take a corresponding multiple arguments.

如果需要在测试方法之间重新初始化测试对象,您可能还想使用我在此相关问题

If you need to reinitialize the object under test between test methods, you might also want to use the trick I described in this related question.

我相信 TestNG ,这可能是升级路径的另一种选择。

I believe similar things are possible in TestNG, which might be another choice for your upgrade path.

这篇关于Java - 合同测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆