【发布时间】:2013-08-14 19:16:13
【问题描述】:
作为一名 TDD 从业者,我想测试我编写的所有代码。
在过去的几年里,我编写了许多多线程代码,其中一部分测试非常麻烦。
当我必须断言可能在 run() 循环期间发生的事情时,我最终会得到一些类似这样的断言:
assertEventually(timeout, assertion)
我知道Mockito 对此有解决方案,但仅适用于 verify 调用。我也知道 JUnit 有一个 timeout 属性,它有助于避免挂起(或永久)测试。但我想要的是能够让我断言随着时间的推移可能会成为现实的东西。
所以我的问题是,有人知道提供此功能的库吗?
到目前为止,这是我的解决方案:
private void assertEventually(int timeoutInMilliseconds, Runnable assertion){
long begin = System.currentTimeMillis();
long now = begin;
Throwable lastException = null;
do{
try{
assertion.run();
return;
}catch(RuntimeException e){
lastException = e;
}catch(AssertionError e){
lastException = e;
}
now = System.currentTimeMillis();
}while((now - begin) < timeoutInMilliseconds);
throw new RuntimeException(lastException);
}
使用结果如下:
assertEvetuallyTrue(1000, new Runnable() {
public void run() {
assertThat(Thread.activeCount()).isEqualTo(before);
}
});
【问题讨论】:
-
您在代码示例中断言什么?方法名称暗示某事物的值为 true 的断言,但代码仅执行 Runnable 并确保它不会出错。
-
我假设您将使用某种断言来测试您的条件。所以他们会抛出有意义的异常来帮助调试你的代码。我举个例子。
-
我原以为 assertEventually 会在超时时抛出异常。在您的示例中,它看起来像是试图抛出 null。此外,抛出
AssertError可能是有意义的。 -
确实也必须预料到 AssertionError。但我仍在一个可用的库中寻找类似的东西。
-
是的,我知道没有图书馆这样做。我用 junit 超时做了一个非常相似的事情,然后在我的竞争条件测试周围循环
while (true)。
标签: java multithreading unit-testing