Java 在Mockito中,如何使用顺序段中的平行段验证顺序?
我有一些代码,可以按顺序执行一些工作,并行执行一些操作,然后在并行工作完成后按顺序执行更多的工作。我不关心并行工作的顺序是什么,只是发生在中间。使用McCito,如何验证并行工作发生在顺序工作的中间,而不关心中间并行调用的顺序? 我知道我可以使用来验证所有调用之间的严格顺序,或者从顺序检查中完全排除一些调用,但这并不能完全处理我的用例。此外,由于我们处理的是并发代码,因此它无法处理这样一个事实,即理想情况下,我们希望验证最终的顺序方法应该只在并行方法完成后才被调用,而不仅仅是在调用它们之后Java 在Mockito中,如何使用顺序段中的平行段验证顺序?,java,unit-testing,concurrency,mocking,mockito,Java,Unit Testing,Concurrency,Mocking,Mockito,我有一些代码,可以按顺序执行一些工作,并行执行一些操作,然后在并行工作完成后按顺序执行更多的工作。我不关心并行工作的顺序是什么,只是发生在中间。使用McCito,如何验证并行工作发生在顺序工作的中间,而不关心中间并行调用的顺序? 我知道我可以使用来验证所有调用之间的严格顺序,或者从顺序检查中完全排除一些调用,但这并不能完全处理我的用例。此外,由于我们处理的是并发代码,因此它无法处理这样一个事实,即理想情况下,我们希望验证最终的顺序方法应该只在并行方法完成后才被调用,而不仅仅是在调用它们之后 pu
public interface MockedClass {
void initialMethodOne();
void initialMethodTwo();
void parallelMethodOne();
void parallelMethodTwo();
void finalMethodOne();
void finalMethodTwo();
}
虽然我没有看到在任何地方或其他地方显式调用它,但实验表明,可以同时使用多个
InOrder
对象来验证相同的调用。然后,Once可以独立地验证每个路径(如果存在多个并行调用,则可能在循环中)
然而,这并不能解决的一件事是,最终方法必须在并行方法完成后才能被调用。Mockito似乎不支持此类验证,但我们可以做以下工作作为解决方法:
@Test
public void doOrderedAndParallelWork3() {
MockedClass mockedClass = mock(MockedClass.class);
CheckComplete methodOneComplete = mock(CheckComplete.class);
CheckComplete methodTwoComplete = mock(CheckComplete.class);
doAnswer(answersWithDelay(200, invocation -> {methodOneComplete.complete(); return null;}))
.when(mockedClass).parallelMethodOne();
doAnswer(answersWithDelay(100, invocation -> {methodTwoComplete.complete(); return null;}))
.when(mockedClass).parallelMethodTwo();
new InOrderExample(mockedClass).doOrderedAndParallelWork();
InOrder inOrder = inOrder(mockedClass, methodOneComplete, methodTwoComplete);
inOrder.verify(mockedClass).initialMethodOne();
inOrder.verify(mockedClass).initialMethodTwo();
inOrder.verify(mockedClass).finalMethodOne();
inOrder.verify(mockedClass).finalMethodTwo();
InOrder inOrder1 = inOrder(mockedClass, methodOneComplete);
inOrder1.verify(mockedClass).initialMethodTwo();
inOrder1.verify(methodOneComplete).complete();
inOrder1.verify(mockedClass).finalMethodOne();
InOrder inOrder2 = inOrder(mockedClass, methodTwoComplete);
inOrder2.verify(mockedClass).initialMethodTwo();
inOrder2.verify(methodTwoComplete).complete();
inOrder2.verify(mockedClass).finalMethodOne();
}
private interface CheckComplete {
void complete();
}
虽然我没有看到在任何地方或其他地方显式调用它,但实验表明,可以同时使用多个
InOrder
对象来验证相同的调用。然后,Once可以独立地验证每个路径(如果存在多个并行调用,则可能在循环中)
然而,这并不能解决的一件事是,最终方法必须在并行方法完成后才能被调用。Mockito似乎不支持此类验证,但我们可以做以下工作作为解决方法:
@Test
public void doOrderedAndParallelWork3() {
MockedClass mockedClass = mock(MockedClass.class);
CheckComplete methodOneComplete = mock(CheckComplete.class);
CheckComplete methodTwoComplete = mock(CheckComplete.class);
doAnswer(answersWithDelay(200, invocation -> {methodOneComplete.complete(); return null;}))
.when(mockedClass).parallelMethodOne();
doAnswer(answersWithDelay(100, invocation -> {methodTwoComplete.complete(); return null;}))
.when(mockedClass).parallelMethodTwo();
new InOrderExample(mockedClass).doOrderedAndParallelWork();
InOrder inOrder = inOrder(mockedClass, methodOneComplete, methodTwoComplete);
inOrder.verify(mockedClass).initialMethodOne();
inOrder.verify(mockedClass).initialMethodTwo();
inOrder.verify(mockedClass).finalMethodOne();
inOrder.verify(mockedClass).finalMethodTwo();
InOrder inOrder1 = inOrder(mockedClass, methodOneComplete);
inOrder1.verify(mockedClass).initialMethodTwo();
inOrder1.verify(methodOneComplete).complete();
inOrder1.verify(mockedClass).finalMethodOne();
InOrder inOrder2 = inOrder(mockedClass, methodTwoComplete);
inOrder2.verify(mockedClass).initialMethodTwo();
inOrder2.verify(methodTwoComplete).complete();
inOrder2.verify(mockedClass).finalMethodOne();
}
private interface CheckComplete {
void complete();
}
@Test
public void doOrderedAndParallelWork2() {
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();
// Verify the strictly sequential portion
InOrder inOrder = inOrder(mockedClass);
inOrder.verify(mockedClass).initialMethodOne();
inOrder.verify(mockedClass).initialMethodTwo();
inOrder.verify(mockedClass).finalMethodOne();
inOrder.verify(mockedClass).finalMethodTwo();
// Verify the first call is executed in the right order relative to the sequential portion
InOrder inOrder1 = inOrder(mockedClass);
inOrder1.verify(mockedClass).initialMethodTwo();
inOrder1.verify(mockedClass).parallelMethodOne();
inOrder1.verify(mockedClass).finalMethodOne();
// Verify the second call is executed in the right order relative to the sequential portion
InOrder inOrder2 = inOrder(mockedClass);
inOrder2.verify(mockedClass).initialMethodTwo();
inOrder2.verify(mockedClass).parallelMethodTwo();
inOrder2.verify(mockedClass).finalMethodOne();
}
@Test
public void doOrderedAndParallelWork3() {
MockedClass mockedClass = mock(MockedClass.class);
CheckComplete methodOneComplete = mock(CheckComplete.class);
CheckComplete methodTwoComplete = mock(CheckComplete.class);
doAnswer(answersWithDelay(200, invocation -> {methodOneComplete.complete(); return null;}))
.when(mockedClass).parallelMethodOne();
doAnswer(answersWithDelay(100, invocation -> {methodTwoComplete.complete(); return null;}))
.when(mockedClass).parallelMethodTwo();
new InOrderExample(mockedClass).doOrderedAndParallelWork();
InOrder inOrder = inOrder(mockedClass, methodOneComplete, methodTwoComplete);
inOrder.verify(mockedClass).initialMethodOne();
inOrder.verify(mockedClass).initialMethodTwo();
inOrder.verify(mockedClass).finalMethodOne();
inOrder.verify(mockedClass).finalMethodTwo();
InOrder inOrder1 = inOrder(mockedClass, methodOneComplete);
inOrder1.verify(mockedClass).initialMethodTwo();
inOrder1.verify(methodOneComplete).complete();
inOrder1.verify(mockedClass).finalMethodOne();
InOrder inOrder2 = inOrder(mockedClass, methodTwoComplete);
inOrder2.verify(mockedClass).initialMethodTwo();
inOrder2.verify(methodTwoComplete).complete();
inOrder2.verify(mockedClass).finalMethodOne();
}
private interface CheckComplete {
void complete();
}