JUnit测试预期的超时

时间:2016-05-20 20:08:16

标签: java unit-testing testing junit

我通过TCP套接字进行通信测试,我希望服务器在发送特定消息时在设定的时间范围内不响应。

服务器行为是我无法控制的。

如果测试未在设定的时间范围内完成,我知道如何测试失败。但我怎么能做相反的事情,让它在时间框架内没有完成?

如果在一秒钟内没有完成,我可以使用@Test (timeout=1000)使测试失败。

但是,使用Junit 4,是否有一个函数来测试预期的超时作为一个积极的结果?即如果在时间范围内完成测试将失败,如果没有则通过测试?

2 个答案:

答案 0 :(得分:7)

好问题。实际上,您只能使用junit工具执行此操作。我的想法是反转Timeout规则行为+使用expected注释的Test属性。唯一的限制是:您必须将测试放在单独的类中,因为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 {
        Thread.sleep(1000);
    }
}

答案 1 :(得分: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);
    }
}