2017-01-22 70 views
0

我发现JUnit的文档在下面的例子:JUnit和InterruptedException的

public static class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout= new Timeout(20); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) {} 
    } 
} 

我明白,只要JUnit的尝试中断第一次测试,它会中断线程在那里上运行,它会抛出一个InterruptedException,导致测试结束。

但是第二个测试(infiniteLoop)呢?它不会抛出任何东西。超时后如何停止?

回答

1

超时规则在单独的线程中运行每个测试,并等待超时。超时后,线程中断。测试运动员将继续进行下一个测试。它不会等待对中断的任何响应,因此测试可以在后台继续运行。

infiniteLoop不会抛出任何InterruptedException但在运行任何剩余测试时继续运行。

所有测试完成后,运行测试的JVM通常会与其中的所有线程一起终止。要么因为线程被标记为守护进程线程,要么通过调用System.exit

见的源代码:

+0

我从你的评论中了解到(在查看源代码之后),junit会尝试以超时方式加入该线程,并检查它是否在超时后仍在运行。如果是,测试将失败。即,即使测试在后台运行,它在失败的加入呼叫之后也会失败。 – sapito

0

它应该在两个测试中抛出,@Rule注释将附加计时器给每个测试。如果测试运行超过20ms,则会触发异常。所以在你的程序中,第二个测试也应该触发InterruptedException。

+0

如果我们单独进行第二项测试,该怎么办?即使有超时,它会永久运行吗? – sapito

+0

不,它会抛出'InterrupedException',因为它仍然有超时。注释允许代码将异常本地化到该测试,但在这种情况下,其他测试会抛出另一个异常。 –

+0

哪里会抛出InterruptedException?这似乎让我感到困惑:)看起来第二个测试不能抛出任何东西,它只是一个简单的循环。 – sapito

0

我试过下面的代码,它工作正常(即两个测试因超时20ms而失败)我正在使用Java 8和JUnit 4.12。

import java.util.concurrent.TimeUnit; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.Timeout; 

public class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) { 
     } 
    } 
} 

注意,我删除了static修改类声明(据我所知,这是不允许的类),我改变了Timeout声明(即一个当前已过时)。