在 junit 中测试多线程时出现奇怪的行为



我遇到了一个问题,导致我真的被难住了一段时间。我敢肯定,这是我不太懂的关于 junit 的东西。

让我们拿一个非常简单的类:

package incubate.thread;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Sleeper implements Runnable{
    @Override
    public void run(){
        try {
            Thread.sleep(5000l);
            System.out.println("done snoozing");
        } catch (InterruptedException ex) {
            Logger.getLogger(Sleeper.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

为线程编写一个非常简单的测试

package incubate.thread;
import org.junit.Test;
public class SleeperTest {
    @Test
    public void testSnooze() throws Exception {
        new Thread(new Sleeper()).start();
    }
    public static void main(String...args){
        new Thread(new Sleeper()).start();
    }
}

您会注意到我在测试类中包含一个"main"方法。当您调用 junit 执行"testSnooze"时,测试会立即退出而不运行线程。

但是,如果您调用main方法,则线程运行良好;它会暂停,然后在末尾打印快速消息

朱尼特导致这种行为怎么办?

关于 ThomasStets 的回答,我建议考虑单独测试run()方法,而无需调用 Thread 的 start()

测试的目的是测试我们编写的代码

我们不应该测试我们没有编写的代码——所以对于单元测试,直接调用run()方法应该足够了。

但是,我们应该测试我们编写的代码是否适用于我们没有编写的代码。如果像线程这样简单,我认为这将包含在验收测试(系统入口点上的黑盒测试)中,没有真正的方法为此编写集成测试。

您的 testSnooze 将返回,而无需等待线程完成。不确定当 JUnit 完成时,仍在休眠的线程会发生什么。我猜 JUnit 只是退出 VM,而不等待任何剩余线程。

如果调用 main 方法,VM 将等待任何非守护进程线程完成。

要使测试正常工作,只需等待线程完成:

@Test
public void testSnooze() throws Exception {
    Thread t = new Thread(new Sleeper());
    t.start();
    t.join();
}

最新更新