java - Junit 模拟异步线程调用
问题描述
我正在尝试对 A 类进行单元测试,其中 A 类如下
Class A{
private final classB = new ClassB();
public Void test(ScheduledEvent scheduledEvent, Context context) {
try {
Thread thread2 = new Thread(() -> doHandleRequest());
thread2.start();
thread2.join(3000);
if (thread2.isAlive()) {
thread2.interrupt();
// sleep for 30 seconds to flush any logs or CFN metrics.
Thread.sleep(30000);
}
} catch (InterruptedException ex) {
}
}
void doHandleRequest() {
try {
classB.sweep();
} catch(Exception ex) {
log.error("Exception in SweepThread while sweeping and deleting lambdas", ex);
}
}
}
Class B{
public void sweep(){
// do something;
}
我想对 thread2.isAlive() 条件为真并且进入 if 块的 A 类场景进行单元测试。
解决方案
首先,您需要更改创建ClassB
对象的方式以允许模拟,每次都创建对象时无法做到这一点。
你可以这样做
public class ClassA {
private final ClassB b;
// this will allow you to inject mock from outside, as it's final, can be initialized only via a constructor.
public ClassA(ClassB b){
this.b = b;
}
// your remaining code
}
现在,在您的测试用例中,您需要注入模拟。
@Test
public void test() throws InterruptedException {
ClassB classB = Mockito.mock(ClassB.class);
ClassA classA = new ClassA(classB);
MockitoAnnotations.initMocks(this); // this will initialize mocks
//above can be skipped if you are using annotations for the same
Mockito.stubVoid(classB)
.toAnswer(invocationOnMock -> {
Thread.sleep(4000);
return null;
}).on().sweeps();
parent.test(null, null);
}
为确保您的线程在 之后是活动的join
,您可以在 的模拟方法中添加延迟classB
。
由于你的方法返回void,我们需要使用stubVoid
,否则会是这样。
Mockito.when(mock.method(/* args, if, any */)).thenAnswer(mock -> {
Thread.sleep(delayInMilliseconds);
return desiredValue;
})
推荐阅读
- drop-down-menu - Coldfusion,下拉菜单,单个选项值可以包含多个变量吗?
- javascript - (PHP)如何使用会话保护目录(及其文件)
- reactjs - 关闭子组件后如何防止父组件状态重置为原始状态
- listview - NativeScript RadListView 图像动画不起作用
- python - 通过 Gitlab 合并请求向 Jenkins 传递参数
- python - 如何从 Colab 将文件输出到谷歌团队(共享)驱动器?
- html - Body 标签在我的代码中使用了两次。如何修复此错误以便我的代码可以通过验证?
- python - 训练 keras 模型时,维度如何工作?
- django - Django 测试返回一个 AnonymousUser 实例而不是新用户
- jquery - 在循环之外获取当前变体 id 并将其用于服务器端功能。WooCommerce / jQuery