【问题标题】:How to avoid conflict between Mockito and PowerMockito?如何避免 Mockito 和 PowerMock 之间的冲突?
【发布时间】:2014-10-09 09:01:47
【问题描述】:

我需要测试一些非常简单的类。第一个是Child类:

public class Child extends Parent {

    public int newMethod() {
        anotherMethod();
        protectedMethod();
        return protectedMethodWithIntAsResult();
    }

    public void anotherMethod() {
        // method body no so important
    }
}

比我有一个Parent 类:

public class Parent {
    protected void protectedMethod() {
        throw new RuntimeException("This method shouldn't be executed in child class!");
    }

    protected int protectedMethodWithIntAsResult() {
        throw new RuntimeException("This method shouldn't be executed in child class!");
    }
}

最后是我的单一测试方法的测试类:

@PrepareForTest({Child.class, Parent.class})
public class ChildTest extends PowerMockTestCase {

    @Test
    public void test() throws Exception {

        /** Given **/
        Child childSpy = PowerMockito.spy(new Child());
        PowerMockito.doNothing().when(childSpy, "protectedMethod");
        PowerMockito.doReturn(100500).when(childSpy, "protectedMethodWithIntAsResult");

        /** When **/
        int retrieved = childSpy.newMethod();

        /** Than **/
        Assert.assertTrue(retrieved == 100500);
        Mockito.verify(childSpy, times(1)).protectedMethod();
        Mockito.verify(childSpy, times(1)).protectedMethodWithIntAsResult();
        Mockito.verify(childSpy, times(1)).anotherMethod(); // but method was invoked 3 times.
    }
}

我上次验证有问题。程序抛出异常:

org.mockito.exceptions.verification.TooManyActualInvocations: 
child.anotherMethod();
Wanted 1 time:
-> at my.project.ChildTest.test(ChildTest.java:30)
But was 3 times. Undesired invocation:

我不明白为什么。任何想法为什么会发生?

【问题讨论】:

  • 我建议在被测类中模拟方法调用不是一个好的测试实践。您应该简单地验证预期结果和任何潜在的副作用。
  • 你测试的哪一行是30
  • Mockito.verify(childSpy, times(1)).anotherMethod();
  • 尝试将系统输出放入anotherMethod 并在每个测试方法之后。这应该为您提供有关何时/如何调用 anotherMethod 的线索。让我们知道结果。
  • 其实 anotherMethod() 调用成功了。而且它只打印了一次消息。

标签: java unit-testing testng mockito powermock


【解决方案1】:

当您调用int retrieved = childSpy.newMethod() 时,问题就出现了,因为您在其中调用了anotherMethod()protectedMethod()

Mockito 假定您将只调用每个方法,但 newMethod 在内部调用 protectedMethodanotherMethodanotherMethod 已经被调用过一次。

如果您删除对newMethodanotherMethod 的调用,测试将正常运行。

【讨论】:

  • anotherMethod 在哪里被调用过一次?被测方法调用了其他 3 个方法。测试验证这些方法中的每一个都被调用了一次。您是否建议更改被测代码以使测试通过?测试必须通过newMethod,因为这是被测方法并且测试不会调用anotherMethod
  • 测试确实调用anotherMethodnewMethod请看测试代码。
  • 实际上,它调用Mockito.verify().anotherMethod,这是在模拟上验证调用的方法。
  • childSpy.newMethod() 被测试调用时,newMethod 内部调用 anotherMethod 被 Mockito 模拟。现在 anotherMethod 已经被嘲笑了,这就是为什么 Mockito 在最后一行再次被调用时抱怨的原因。
  • 你在哪里看到anotherMethod被嘲笑了?我只看到 protectedMethodprotectedMethodWithIntAsResult 的嘲笑(实际上是存根,因为这是一个间谍)。
猜你喜欢
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 2019-02-08
  • 2011-11-07
  • 1970-01-01
相关资源
最近更新 更多