Junit测试挂起我的异步线程

时间:2017-03-30 03:19:38

标签: java spring multithreading junit spring-test-mvc

我在我的服务的@Postconstruct方法上分叉一个新线程,在新线程中,一个无限循环正在运行。

我的测试只是使用spring mvc test调用服务:

ResultActions result = this.mockMvc.perform(post("/test").with(httpBasic(user, pwd)).contentType("application/json").content(test))
        .andDo(MockMvcResultHandlers.print())
        .andExpect(status().isOk());

测试只是挂起,等待无限循环线程停止。但是当服务正常启动时,测试就可以了。知道为什么吗?以及如何解决它。

这是我的服务java中的代码:

@Postconstruct
private void init() {
   invoke();
}

private void invoke() {

 Runnable task = () -> {
     while(true) { ... }
  }
 Thread t;
 for(int i=0; i<3; i++) {
     t = new Thread(task);
     t.setName("test-" + i);
     t.start();
  }
 }

2 个答案:

答案 0 :(得分:2)

建议:退一步使用“裸机”线程。有很好的抽象概念,比如ExecutorService和Futures and Promises之类的东西。

重点是:可以使用依赖注入为生产代码提供这样的ExecutorService;然后你可以定义自己的service ...来完成相同主题的所有内容。

含义:避免处理多个线程的单元测试 - 因为这通常会导致额外的等待或“剥落”,因为您现在从未确切地测试过多长时间。

答案 1 :(得分:0)

看看这个例子(带有调试器)

请注意,在完成所有线程之前,不会退出main。 您可以通过在一段时间内放置断点(运行)并轻松更改运行的值来轻松完成此操作。关闭所有3个线程后,主线程将退出。

class Test {
    public static void main(String[] args) {
        Runnable task = () -> {
            boolean run = true;
            while (run) {
                System.out.println("running");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Thread t = new Thread(task);
            t.setName("test-" + i);
            t.start();
            threads.add(t);
        }
    }
}

另一种方法是使用join,它将在程序完成之前显式等待线程完成。

for (Thread t : threads) {
    try {
        t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

虽然有任何活动的线程在运行,程序将无法完成。