Java 在Mockito中,如何使用顺序段中的平行段验证顺序?

Java 在Mockito中,如何使用顺序段中的平行段验证顺序?,java,unit-testing,concurrency,mocking,mockito,Java,Unit Testing,Concurrency,Mocking,Mockito,我有一些代码,可以按顺序执行一些工作,并行执行一些操作,然后在并行工作完成后按顺序执行更多的工作。我不关心并行工作的顺序是什么,只是发生在中间。使用McCito,如何验证并行工作发生在顺序工作的中间,而不关心中间并行调用的顺序? 我知道我可以使用来验证所有调用之间的严格顺序,或者从顺序检查中完全排除一些调用,但这并不能完全处理我的用例。此外,由于我们处理的是并发代码,因此它无法处理这样一个事实,即理想情况下,我们希望验证最终的顺序方法应该只在并行方法完成后才被调用,而不仅仅是在调用它们之后 pu

我有一些代码,可以按顺序执行一些工作,并行执行一些操作,然后在并行工作完成后按顺序执行更多的工作。我不关心并行工作的顺序是什么,只是发生在中间。使用McCito,如何验证并行工作发生在顺序工作的中间,而不关心中间并行调用的顺序?

我知道我可以使用来验证所有调用之间的严格顺序,或者从顺序检查中完全排除一些调用,但这并不能完全处理我的用例。此外,由于我们处理的是并发代码,因此它无法处理这样一个事实,即理想情况下,我们希望验证最终的顺序方法应该只在并行方法完成后才被调用,而不仅仅是在调用它们之后

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();
}