【问题标题】:Validate methods execute in parallel验证方法并行执行
【发布时间】:2016-07-13 09:06:00
【问题描述】:

我正在创建一个单元测试来显示两个方法并行执行。为此,我模拟了这两种方法,并让它们都有 2 秒的延迟。然后我验证单元测试花费的时间少于 4 秒(因此我可以确定这些操作不是按顺序执行的,因为那样会花费超过 4 [2*2] 秒)。

有没有更好的办法?

【问题讨论】:

  • 在模拟中记录开始和结束。两者都应该在任一结束之前开始,您可以使用日志条目来检查这一点(或增加一个共享变量 - 原子地! - 当任务开始时,在任务结束时减少,跟踪它的最大值,并检查答案是否为两个) .等等。
  • 这两种方法是否来自同一个模拟?
  • @LorenzoMurrocu 我们希望支持这两种情况。相同的模拟和不同的模拟。

标签: scala mockito scalatest


【解决方案1】:

我会使用 InOrder 功能。 这是两个方法来自同一个模拟的示例:

@Test
public void foo() {
    MyClass mock = Mockito.mock(MyClass.class);
    Mockito.when(mock.methodOne())thenAnswer(new Answer<ReturnType>()
    {

        @Override
        public ReturnType answer(InvocationOnMock invocation) throws Throwable
        {
            // Implement the delay or parallel execution
            . . . 
            mock.methodThree(); // This invocation is just a hook to intercept the end of this method execution
            return something;
        }
    });

    Mockito.when(mock.methodTwo())thenAnswer(new Answer<ReturnType>()
    {

        @Override
        public ReturnType answer(InvocationOnMock invocation) throws Throwable
        {
            // Implement the delay or the parallel execution
            . . .
            mock.methodThree(); // This invocation is just a hook to intercept the end of this method execution
            return something;
        }
    });



    // Here there should be the call to the real method that calls the two methods in parallel: 
    // !!HERE!!
    // mock1.methodOne();
    // mock2.methodTwo();

    InOrder inOrder = Mockito.inOrder(mock1, mock2);
    inOrder.verify(mock1).methodOne(); //asserts that methodOne should be invoked first
    inOrder.verify(mock2).methodTwo(); //asserts that methodTwo should be invoked after methodOne
    inOrder.verify(mock3, Mockito.calls(2)).methodThree(); //asserts that methodThree, that is invoked at the end of methodOne, is invoked after the methodTwo invocation.  These asserts together tell us that methodTwo was called during the execution of methodOne.
}

您也可以将 InOrder 与多个模拟一起使用:

@Test
public void foo() {
    MyClass mock1 = Mockito.mock(MyClass.class);
    MyClass mock2 = Mockito.mock(MyClass.class);
    OtherClass mock3 = Mockito.mock(OtherClass.class);

    Mockito.when(mock1.methodOne())thenAnswer(new Answer<ReturnType>()
    {

        @Override
        public ReturnType answer(InvocationOnMock invocation) throws Throwable
        {
            // Implement the delay or the parallel execution
            . . .
            mock3.methodThree(); // This invocation is just a hook to intercept the end of this method execution
            return something;
        }
    });

    Mockito.when(mock2.methodTwo())thenAnswer(new Answer<ReturnType>()
    {

        @Override
        public ReturnType answer(InvocationOnMock invocation) throws Throwable
        {
            // Implement the delay or the parallel execution 
            . . .
            mock3.methodThree(); // This invocation is just a hook to intercept the end of this method execution
            return something;
        }
    });


    // Here there should be the call to the real method that calls the two methods in parallel: 
    // !!HERE!!
    // mock1.methodOne();
    // mock2.methodTwo();

    InOrder inOrder = Mockito.inOrder(mock1, mock2);
    inOrder.verify(mock1).methodOne(); //asserts that methodOne should be invoked first
    inOrder.verify(mock2).methodTwo(); //asserts that methodTwo should be invoked after methodOne
    inOrder.verify(mock3, Mockito.calls(2)).methodThree(); //asserts that methodThree, that is invoked at the end of methodOne, is invoked after the methodTwo invocation. These asserts together tell us that methodTwo was called during the execution of methodOne.
}

在这个例子中,mock3 只是一个实例,它的唯一目的是挂钩两个方法的执行结束,所以应该用doNothing 模拟它。也许在您的场景中,这可以通过不同的方式实现。

编辑: 我现在将更好地解释我的答案:在我分享的示例中,只有模拟,所以测试没用。在我添加!!HERE!! 的代码中,应该有对实际并行调用两个模拟方法的真实方法的调用。或者,Answer 的两个实例应该被实现为并行执行,但是只有模拟的测试没有用。 鉴于此,我在示例中配置的 inOrder 会验证第二次调用发生在第一次调用结束之前(查看我添加的 cmets)。

有关 InOrder 接口的更多信息: http://site.mockito.org/mockito/docs/current/org/mockito/InOrder.html http://www.tutorialspoint.com/mockito/mockito_ordered_verification.htm

【讨论】:

  • 谢谢。我不明白这如何验证 methodOne 和 methodTwo 并行执行。你能解释一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 2016-03-22
  • 2021-01-26
相关资源
最近更新 更多