繁体   English   中英

JUnit 测试预期超时

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM