我有很多junit 4测试类,有很多测试。 其中许多测试需要DataSource来访问数据库。
为了加快测试速度,我想为所有测试类共享一个DataSource。 这样可以避免连接成本。
所以我把DataSource放在一个静态变量中。
但我还没有办法关闭它!
使用@Rule + TestWatcher,我们可以在单个测试之前和之后执行代码... 使用@ClassRule + TestWatcher,我们可以在单个测试类之前和之后执行代码......
但是如何在执行所有执行的测试类后执行代码?
测试套件似乎不合适,因为我正在执行junits测试的全部,一个或任何子集。
有什么想法吗?
答案 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()方法更可靠。
如果进程中断,则不会被调用,但在这种情况下,无论如何都无法进行任何操作。所以我没有发现主要缺点。
感谢。