13

我有一个界面,例如:

public interface Thing {
  FrobResult frob(FrobInput); 
}

以及我正在尝试测试的该接口的几个实现(例如NormalThing, ImmutableThing) 。AsyncThing

我的许多测试方法实际上都是为了确保接口正确实现,因此在每个Thing实现中都是重复的。在 JUnit 3 中,一个常见的解决方案是创建一个基类(扩展TestCase),然后由每个实现类对其进行子类化。但这是 JUnit 4 的正确方法吗?

(我相信)按偏好升序排列的可能替代方案:

  1. 剪切'n'粘贴重复的测试方法。一点也不干,但我想测试中的担忧不如生产代码中的担忧。

  2. 创建一个带有@Test方法的抽象类,并为每个实现测试类对其进行子类化。(在 JUnit 3 测试中很常见——在 JUnit 4 中这仍然是一个好方法吗?)

  3. 将常用的测试方法放入一个辅助类中,并在每个实现中调用它。(组合而不是继承。)

做#3的最佳实践是什么?也许@RunWith(Parameterized.class)是每个实现都参数化的测试?还是有更好的方法来实现这一点?

4

2 回答 2

6

是的,创建一个基类,然后由 JUnit4 中的每个实现类对其进行子类化是正确的方法。

我更喜欢接口的基本测试类是抽象的,即你的“替代”2,因为我在模仿测试代码的生产代码的继承层次结构方面取得了很好的经验。因此,如果您有接口I和实现S1S2并且S3,您将创建抽象测试类TestI和测试类TestS1TestS2并且TestS3

测试用例应该会说话,即讲故事。通过像往常一样仔细选择方法名称并仅使用干净的行为子类型,继承不会混淆这一点。

于 2012-11-01T21:18:50.467 回答
1

我对 JUnit 和TestNG测试用例使用#2 方法。这是最方便和易于维护的。它也很容易上手(因为它原生于 OOD 以具有具有通用方法的基类)。对我来说,单元测试类与常规项目类没有什么不同……所以我确实应用了类似的设计考虑。

于 2012-11-01T21:28:40.657 回答