【问题标题】:JUnit testing an asynchronous method with MockitoJUnit 使用 Mockito 测试异步方法
【发布时间】:2018-12-17 23:33:05
【问题描述】:

我已经使用 Spring Framework(版本 5.0.5.RELEASE)在 Java 1.8 类中实现了一个异步方法:

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 测试该类。我将其设置如下,目的是模拟 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() 的调用是异步的这一事实有关。

我们将不胜感激。

【问题讨论】:

    标签: java spring junit mockito spring-scheduled


    【解决方案1】:

    解决方案是在 Mockito 验证步骤中添加超时和检查,以确保已调用适当次数的模拟组件的方法:

        Mockito.verify(myComponentAsAMock, Mockito.timeout(1000).times(1)).doOtherStuff(ArgumentMatchers.any(MyClass.class));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      相关资源
      最近更新 更多