[英]JUnit test for an expected timeout
我通过 TCP 套接字进行了通信测试,我希望服务器在我发送某个消息时不会在设定的时间范围内响应。
服务器的行为是我无法控制的。
如果测试没有在设定的时间范围内完成,我知道如何失败。 但是我怎么能做相反的事情,让它在时间范围内没有完成呢?
如果没有在一秒钟内完成,我可以使用@Test (timeout=1000)
使测试失败。
但是,使用 Junit 4,是否有一个函数可以测试预期的超时作为肯定结果? 即如果在时间范围内完成,测试将失败,如果没有通过?
好问题。 实际上你可以只使用junit
工具来做到这一点。 我的想法是反转Timeout
规则行为+使用Test
注释的expected
属性。 唯一的限制:您必须将测试放在单独的类中,因为Rule
适用于其中的所有测试:
public class Q37355035 {
private static final int MIN_TIMEOUT = 100;
@Rule
public Timeout timeout = new Timeout(MIN_TIMEOUT) {
public Statement apply(Statement base, Description description) {
return new FailOnTimeout(base, MIN_TIMEOUT) {
@Override
public void evaluate() throws Throwable {
try {
super.evaluate();
throw new TimeoutException();
} catch (Exception e) {}
}
};
}
};
@Test(expected = TimeoutException.class)
public void givesTimeout() throws InterruptedException {
TimeUnit.SECONDS.sleep(1);
}
}
我正在建立 Andremoniy 的出色答案,如果您喜欢这个答案,请不要忘记支持他的答案!
如果测试没有在预期的时间范围内完成,我使用以下修改跳过测试。 这样做的好处是测试将被 JUnit 标记为已跳过而不是成功。 这有利于乐观地执行测试,这些测试有时会挂起或完成不够快,但您不想将它们标记为失败或删除它们。
public class OptimisticTestClass {
private static final int TEST_METHOD_TIMEOUT_MS = 100;
@Rule
public Timeout timeout = new Timeout(TEST_METHOD_TIMEOUT_MS, TimeUnit.MILLISECONDS) {
public Statement apply(Statement base, Description description) {
return new FailOnTimeout(base, TEST_METHOD_TIMEOUT_MS) {
@Override
public void evaluate() throws Throwable {
try {
super.evaluate();
} catch (TestTimedOutException e) {
Assume.assumeNoException("Test did not finish in the allocated time, skipping!", e);
}
}
};
}
};
// The test times out and is skipped
public void givesTimeout() throws InterruptedException {
Thread.sleep(1000);
}
}
Java 9 更简单
CompletableFuture.supplyAsync(() -> dormammu.bargain())
.orTimeout(1, TimeUnit.SECONDS)
.handle((result, throwable) -> {
if (!(throwable instanceof TimeoutException)) {
Assertions.fail();
}
return result;
}).get();
如果该方法在 1 秒内没有返回,它将超时。 在 handle 方法中,您可以确保 TimeoutException 被抛出,否则测试失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.