在JUnit 4中重用测试实现?

Dan*_*den 12 java code-reuse unit-testing junit4

我有一个界面,例如:

public interface Thing {
  FrobResult frob(FrobInput); 
}
Run Code Online (Sandbox Code Playgroud)

和界面的实现(例如NormalThing,ImmutableThing,AsyncThing),我想测试.

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

可能的替代方案(我相信)优先顺序升序:

  1. Cut'n'paste重复的测试方法.根本不干,但我觉得在测试中不如生产代码那么令人担忧.

  2. 使用@Test方法创建一个抽象类,并为每个实现测试类创建子类.(通常在JUnit 3测试中看到 - 这仍然是进入JUnit 4的好方法吗?)

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

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

Dav*_*Far 6

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

我更喜欢接口的基本测试类是抽象的,即你的"替代"2,因为我在模拟测试代码的生产代码中的继承层次结构方面有很好的经验.因此,如果您有接口I和实现S1,S2并且S3您创建了抽象测试类TestI和测试类TestS1,TestS2并且TestS3.

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