Search code examples
javaunit-testingtestingjunit

JUnit test for an expected timeout


I have a test of communication over a TCP socket where I expect the server to not respond within a set time frame when I send a certain message.

The servers behaviour is nothing I can control.

I know how to fail a test if it has not completed within a set time frame. But how can I do the opposite, make it pass for not completing within the timeframe?

I can use @Test (timeout=1000) to make a test fail if not complete within a second.

But, using Junit 4, is there a function to test for an expected timeout as a positive result? I.e. The test will fail if completed within the time frame and pass if not?


Solution

  • Good question. Actually you can do this using only junit tools. My idea is to inverse Timeout rule behaviour + use expected attribute of Test annotation. The only one limitation: you have to place your test in separate class, because Rule applies to all tests inside it:

    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);
        }
    }