如何关闭junits之间共享的资源?

时间:2013-01-30 17:13:58

标签: java junit

我有很多junit 4测试类,有很多测试。 其中许多测试需要DataSource来访问数据库。

为了加快测试速度,我想为所有测试类共享一个DataSource。 这样可以避免连接成本。

所以我把DataSource放在一个静态变量中。

但我还没有办法关闭它!

使用@Rule + TestWatcher,我们可以在单个测试之前和之后执行代码... 使用@ClassRule + TestWatcher,我们可以在单个测试类之前和之后执行代码......

但是如何在执行所有执行的测试类后执行代码?

测试套件似乎不合适,因为我正在执行junits测试的全部,一个或任何子集。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

您可以使用ClassRule

public static class GlobalDataSource extends ExternalResource
  private int count = 0;
  private DataSource dataSource;

  private GlobalDataSource() {};

  public static final GlobalDataSource INSTANCE = new GlobalDataSource();

  public DataSource get() {
    if (dataSource == null) {
      throw new IllegalStateException();
    }
    return dataSource;
  }

  @Override
  protected void before() throws Throwable {
    if (count++ == 0) {
      dataSource = createDataSource();
    }
  }

  @Override
  protected void after() {
    if (--count == 0) {
      try {
        destroyDataSource(dataSource);
      } finally {
        dataSource = null;
      }
    }
  };
};

在你的测试中:

@RunWith(JUnit4.class)
public class FooTest {
  @ClassRule public static GlobalDataSource source = GlobalDataSource.INSTANCE;

  @Test
  public void readDataSource() {
    ...
  }
}

然后创建一个套件:

@RunWith(Suite.class)
@SuiteClasses(FooTest.class, BarTest.class ...)
public class AllTests {
  @ClassRule public static GlobalDataSource source = GlobalDataSource.INSTANCE;
}

请注意,测试中的全局状态与代码中的全局状态一样有问题。一次测试失败可能导致其他测试失败。

答案 1 :(得分:0)

在这种情况下,安装JVM shutdown hook并不会显得过于丑陋。

比仅在对象被垃圾收集时调用的finalize()方法更可靠。

如果进程中断,则不会被调用,但在这种情况下,无论如何都无法进行任何操作。所以我没有发现主要缺点。

感谢。