JUnit тестирует асинхронный метод с помощью Mockito - PullRequest
0 голосов
/ 18 декабря 2018

Я реализовал асинхронный метод в классе Java 1.8 с использованием Spring Framework (версия 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.Я настроил его следующим образом, чтобы высмеять вызов метода 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. Я замечаю, что генерируются исключения NullPointerException:

[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 () является асинхронным.

Любая помощь будет принята.

1 Ответ

0 голосов
/ 18 декабря 2018

Решением было добавить шаг проверки Mockito с тайм-аутом и проверкой, чтобы убедиться, что метод проверяемого компонента вызывался соответствующее количество раз:

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