У меня есть некоторый код, который выполняет некоторую работу последовательно, выполняет некоторые операции параллельно, а затем выполняет некоторую дополнительную работу последовательно, когда параллельная работа завершена. Мне все равно, в каком порядке происходит параллельная работа, просто все это происходит посередине. Используя Mockito, как я могу проверить, что параллельная работа происходит в середине последовательной работы, но не заботясь о порядке средних параллельных вызовов?
Я знаю, что могу использовать InOrder для проверки строгого порядка среди всех вызовов или полного исключения некоторых вызовов из проверок порядка, но это не совсем подходит для моего варианта использования. Кроме того, поскольку мы имеем дело с параллельным кодом, он не учитывает тот факт, что в идеале мы хотели бы проверить, что окончательные последовательные методы должны вызываться только после завершения параллельных методов, а не только после их вызова.
public interface MockedClass {
void initialMethodOne();
void initialMethodTwo();
void parallelMethodOne();
void parallelMethodTwo();
void finalMethodOne();
void finalMethodTwo();
}
import java.util.concurrent.CompletableFuture;
public class InOrderExample {
private MockedClass mockedClass;
public InOrderExample(MockedClass mockedClass) {
this.mockedClass = mockedClass;
}
public void doOrderedAndParallelWork() {
mockedClass.initialMethodOne();
mockedClass.initialMethodTwo();
CompletableFuture.allOf(
CompletableFuture.runAsync(mockedClass::parallelMethodOne),
CompletableFuture.runAsync(mockedClass::parallelMethodTwo))
.join();
mockedClass.finalMethodOne();
mockedClass.finalMethodTwo();
}
}
import org.junit.Test;
import org.mockito.InOrder;
import static org.mockito.AdditionalAnswers.answersWithDelay;
import static org.mockito.Mockito.*;
public class InOrderExampleTest {
@Test
public void doOrderedAndParallelWork() {
MockedClass mockedClass = mock(MockedClass.class);
doAnswer(answersWithDelay(200, invocation -> null)).when(mockedClass).parallelMethodOne();
doAnswer(answersWithDelay(100, invocation -> null)).when(mockedClass).parallelMethodTwo();
new InOrderExample(mockedClass).doOrderedAndParallelWork();
InOrder inOrder = inOrder(mockedClass);
// These two must happen first, in order
inOrder.verify(mockedClass).initialMethodOne();
inOrder.verify(mockedClass).initialMethodTwo();
// Not quite what I want; these two must happen after the first two and before the last two, but I don't want
// the test to fail if these two are called in opposite order
inOrder.verify(mockedClass).parallelMethodOne();
inOrder.verify(mockedClass).parallelMethodTwo();
// These two must happen last, in order
inOrder.verify(mockedClass).finalMethodOne();
inOrder.verify(mockedClass).finalMethodTwo();
}
}