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

时间:2015-03-16 18:00:44

标签: java 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方法,则线程运行正常;它会打盹,然后在最后打印快速消息

junit怎么会导致这种行为?

2 个答案:

答案 0 :(得分:2)

进一步论ThomasStets'回答,我建议自己考虑单独测试run()方法,而不要调用Thread start()

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

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

答案 1 :(得分:1)

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

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

让你的测试工作只需等待线程完成:

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