JUnit 使用 Mockito 测试异步方法
JUnit testing an asynchronous method with Mockito
我在 Java 1.8 class 中使用 Spring 框架(版本 5.0.5.RELEASE)实现了一个异步方法:
public class ClassToBeTested {
@Autowired
private MyComponent myComponent;
@Async
public void doStuff(List<MyClass> myObjects) {
CompletableFuture<MyResponseObject>[] futureList = new CompletableFuture[myObjects.size()];
int count = 0;
for (MyClass myObject : myObjects) {
futureList[count] = myComponent.doOtherStuff(myObject);
count++;
}
// Wait until all doOtherStuff() calls have been completed
CompletableFuture.allOf(futureList).join();
... other stuff ...
}
}
我正在尝试使用 JUnit 和 Mockito 测试 class。我已将其设置如下,目的是模拟 doStuff() 方法对组件的调用:
@MockBean
private MyComponent myComponentAsAMock;
@InjectMocks
@Autowired
private ClassToBeTested classToBeTested;
@Test
public void myTest() throws Exception {
// Create object to return when myComponent.doOtherStuff() is called.
CompletableFuture<MyResponseObject> completableFuture = new CompletableFuture<MyResponseObject>();
... populate an instance of MyResponseObject ...
completableFuture.complete(myResponseObject);
// Return object when myComponent.doOtherStuff() is called.
Mockito.when(
myComponentAsAMock.doOtherStuff(ArgumentMatchers.any(MyClass.class)))
.thenReturn(completableFuture);
// Test.
List<MyClass> myObjects = new ArrayList<MyClass>();
MyClass myObject = new MyClass();
myobjects.add(myObject);
classToBeTested.doStuff(myObjects);
}
虽然当我在 Eclipse 中单独 运行 单元测试似乎成功时,但是对整个项目进行 Maven 构建时我注意到 NullPointerExceptions 被抛出:
[ThreadExecutor2] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected error occurred invoking async method 'public void package.ClassToBeTested.doStuff(java.util.List)'.
java.lang.NullPointerException: null
at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1306) ~[na:1.8.0_131]
at java.util.concurrent.CompletableFuture.allOf(CompletableFuture.java:2225) ~[na:1.8.0_131]
at package.ClassToBeTested.doStuff(ClassToBeTested.java:75) ~[classes/:na]
ClassToBeTested.java:
这一行出现错误
CompletableFuture.allOf(completedFutureList).join();
看起来在测试完成后异常消息显示在 Maven 构建输出中(还有其他测试运行,其输出发生在正在显示错误消息),所以我猜这与对 doStuff() 的调用是异步的这一事实有关。
如有任何帮助,我们将不胜感激。
解决方案是在 Mockito 验证步骤中添加超时和检查以确保模拟组件的方法已被调用适当的次数:
Mockito.verify(myComponentAsAMock, Mockito.timeout(1000).times(1)).doOtherStuff(ArgumentMatchers.any(MyClass.class));
我在 Java 1.8 class 中使用 Spring 框架(版本 5.0.5.RELEASE)实现了一个异步方法:
public class ClassToBeTested {
@Autowired
private MyComponent myComponent;
@Async
public void doStuff(List<MyClass> myObjects) {
CompletableFuture<MyResponseObject>[] futureList = new CompletableFuture[myObjects.size()];
int count = 0;
for (MyClass myObject : myObjects) {
futureList[count] = myComponent.doOtherStuff(myObject);
count++;
}
// Wait until all doOtherStuff() calls have been completed
CompletableFuture.allOf(futureList).join();
... other stuff ...
}
}
我正在尝试使用 JUnit 和 Mockito 测试 class。我已将其设置如下,目的是模拟 doStuff() 方法对组件的调用:
@MockBean
private MyComponent myComponentAsAMock;
@InjectMocks
@Autowired
private ClassToBeTested classToBeTested;
@Test
public void myTest() throws Exception {
// Create object to return when myComponent.doOtherStuff() is called.
CompletableFuture<MyResponseObject> completableFuture = new CompletableFuture<MyResponseObject>();
... populate an instance of MyResponseObject ...
completableFuture.complete(myResponseObject);
// Return object when myComponent.doOtherStuff() is called.
Mockito.when(
myComponentAsAMock.doOtherStuff(ArgumentMatchers.any(MyClass.class)))
.thenReturn(completableFuture);
// Test.
List<MyClass> myObjects = new ArrayList<MyClass>();
MyClass myObject = new MyClass();
myobjects.add(myObject);
classToBeTested.doStuff(myObjects);
}
虽然当我在 Eclipse 中单独 运行 单元测试似乎成功时,但是对整个项目进行 Maven 构建时我注意到 NullPointerExceptions 被抛出:
[ThreadExecutor2] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected error occurred invoking async method 'public void package.ClassToBeTested.doStuff(java.util.List)'.
java.lang.NullPointerException: null
at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1306) ~[na:1.8.0_131]
at java.util.concurrent.CompletableFuture.allOf(CompletableFuture.java:2225) ~[na:1.8.0_131]
at package.ClassToBeTested.doStuff(ClassToBeTested.java:75) ~[classes/:na]
ClassToBeTested.java:
这一行出现错误CompletableFuture.allOf(completedFutureList).join();
看起来在测试完成后异常消息显示在 Maven 构建输出中(还有其他测试运行,其输出发生在正在显示错误消息),所以我猜这与对 doStuff() 的调用是异步的这一事实有关。
如有任何帮助,我们将不胜感激。
解决方案是在 Mockito 验证步骤中添加超时和检查以确保模拟组件的方法已被调用适当的次数:
Mockito.verify(myComponentAsAMock, Mockito.timeout(1000).times(1)).doOtherStuff(ArgumentMatchers.any(MyClass.class));