在JUnit中继承一个类 - 这是一个好习惯吗?

时间:2014-07-26 12:27:58

标签: java unit-testing junit

我有这个问题。一个类(实际上有一个公共方法)进行测试,并将~30个测试场景存储在单独的xml文件中。由于一个单元测试类太长(需要在单独的测试中测试所有文件),我决定将它们分成几组(几个类),现在问题就出现了。

单元测试本身实现了很少的其他方法,用于测试(用于获取资源,在不同的事物中格式化日历),因为我得到的这些单元类中的一些我也应该复制这些方法。

我只是想如果我可以为这些方法创建额外的类,并使用简单的继承,或者我应该用这些复制的方法创建每个单元测试?这种情况下的良好做法是什么?

2 个答案:

答案 0 :(得分:4)

如果您需要针对许多不同测试用例的通用测试装置,那么使用抽象基类进行单元测试是完全可以的。例如,使用Spring的小规模集成测试通常会使用一个基类来设置测试运行器和上下文,然后添加他们正在测试的特定组件。

答案 1 :(得分:4)

继承的替代方法是授权,正如Alan Stokes所说。在junit中使用它的一个好方法是:use Rules。提供了一些,但您可以轻松创建自己的规则集。

我们所经历的主要好处是,您可以选择您想要的常用功能。有时你只需要一点点常见的抽象测试类。但是因为你只能拥有全套或者什么都没有,你可能最终会为一个相当简单的单元测试设置一个数据库状态。


在junit Wiki下面的示例中,TemporaryFolder规则添加了测试功能,可以创建临时文件夹和文件。这些将在每次测试执行后删除。

public static class HasTempFolder {
  @Rule
  public TemporaryFolder folder = new TemporaryFolder();

  @Test
  public void testUsingTempFolder() throws IOException {
    File createdFile = folder.newFile("myfile.txt");
    File createdFolder = folder.newFolder("subfolder");
    // ...
  }
} 

另一个好处是你可以很容易地将行为更改为类级别。您可能希望拥有此功能的情况是在数据库或搜索索引中设置昂贵的夹具状态。或者,当您为要运行集成测试的某个ETL过程创建大样本XML时。这只应在执行只读操作时使用。

要将其移至班级,您只需要成员static并添加@ClassRule注释,而不是@Rule

public static class HasDataBaseState {
  @ClassRule
  public static DataBaseState dbState = new DataBaseState();

  @Test
  public void testUsingDataBaseState() throws IOException {
    // perform tests
    dbState.query("select count from table where attribute = 'x'");
  }
}

还有更多功能,但是这些功能在junit wiki上相当不错。我指出的事实是我们最喜欢的事实。