Spring Boot 2 单元测试多线程问题

junit 单元测试不支持多线程

原因

部分 Junit4 TestRunner 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static final int SUCCESS_EXIT=0;
public static final int FAILURE_EXIT=1;
public static final int EXCEPTION_EXIT=2;

public static void main(String args[]){
TestRunner aTestRunner=new TestRunner();
try{
TestResult r=aTestRunner.start(args);
if(!r.wasSuccessful())
System.exit(FAILURE_EXIT);
System.exit(SUCCESS_EXIT);
}catch(Exception e){
System.err.println(e.getMessage());
System.exit(EXCEPTION_EXIT);
}
}

TestResult 部分源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected List<TestFailure> fFailures = new ArrayList();
protected List<TestFailure> fErrors = new ArrayList();

public synchronized boolean wasSuccessful() {
return this.failureCount() == 0 && this.errorCount() == 0;
}


public synchronized int errorCount() {
return this.fErrors.size();
}


public synchronized int failureCount() {
return this.fFailures.size();
}

在 TestRunner 中可以看出,
如果是单线程,当测试主线程执行结束后,不管子线程是否结束,都会回调 TestResult 的 wasSuccessful 方法,然后判断结果是成功还是失败,最后调用相应的 System.exit()方法。
大家都知道这个方法是用来结束当前正在运行中的 java 虚拟机,jvm 都自身难保了,所以子线程也就对不住你咧…

解决办法:

1.简单粗暴地让主线程休眠一段时间,然后让子线程能够运行结束。
但是这个方法的弊端是,你不知道子线程的运行时间,所以需要看脸-.-

Thread.sleep();

2.使用 CountDownLatch 工具类,让主线程阻塞,直到子线程运行结束或者阻塞超时,这个方法要比第一个方法好点。

CountDownLatch countDownLatch = new CountDownLatch(1);
countDownLatch.await(5, TimeUnit.MINUTES);

至于还有其他方法,笔者看到很多大神自己写的 Junit 支持多线程,有兴趣的读者自行度娘…

作者:Mr.Yanphet
链接:https://www.cnblogs.com/yanphet/p/5774291.html
来源:cnblogs
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


Spring Boot 2 单元测试多线程问题
https://blog.josway.cc/2022/04/25/yuque/Spring Boot 2 单元测试多线程问题/
作者
JOSWAY
发布于
2022年4月25日
许可协议