gpt4 book ai didi

java - 如何使用 Mockito 验证重载方法的调用次数?

转载 作者:行者123 更新时间:2023-11-29 05:00:41 27 4
gpt4 key购买 nike

如何检查 bar(Alpha, Baz)称为 bar(Xray, Baz)使用 Mockito - 没有实际调用后者,给定我的 MCVE 类 Foo :

public class Foo {
public String bar(Xray xray, Baz baz) {
return "Xray";
}

public String bar(Zulu zulu, Baz baz) {
return "Zulu";
}

public String bar(Alpha alpha, Baz baz) {
if(alpha.get() instanceof Xray) {
return bar((Xray)alpha.get(), baz);
} else if(alpha.get() instanceof Zulu) {
return bar((Zulu)alpha.get(), baz);
} else {
return null;
}
}
}

目前,我大致有以下 Mockito 增强的 JUnit 测试:

@Test
public void testBar_callsBarWithXray() {
Baz baz = new Baz(); //POJOs
Alpha alpha = new Alpha();
alpha.set(new Xray());

Foo foo = new Foo();
Foo stub = spy(foo); // Spying on Foo, as I want to call the real bar(Alpha, Baz)
// Preventing bar(Xray, Baz) from being called by providing behavior/stub
when(stub.bar(any(Xray.class), any(Baz.class))).thenReturn("ok");
// Calling the real "parent" method
stub.bar(alpha, baz);
// Testing if bar(Xray, Baz) was called by bar(Alpha, Baz)
verify(stub, times(1)).bar(any(Xray.class), any(Baz.class));
}

失败了:

org.mockito.exceptions.verification.TooManyActualInvocations:
foo.bar(
<any>,
<any> );
Wanted 1 time:
-> at FooTest.testBar_callsBarWithXray(FooTest.java:14)
But was 2 times. Undesired invocation:
-> at FooTest.testBar_callsBarWithXray(FooTest.java:12)

我想这是因为 any(Class.class)匹配任何内容,并且不进行类型检查...所以,从 Mockito 的角度来看,我真的在调用 bar()两次:在 FooFooTest (第 12 行)。

我必须做什么才能让测试做我真正想要的:确保 bar(Xray, Baz)当我调用bar(Alpha, baz)时被叫到(同时拦截对 bar(Xray, Baz) 的调用)?

使用 eq()匹配器 ( when(stub.bar(eq(Xray.class), any(Baz.class))... ) 导致编译错误,Cannot resolve method 'bar(Class<Xray>, Baz)' - 但是,我可能不应该那样使用它(eq(xray) 可能更像它)...

此外,在相关说明中,如果我尝试重载 bar(Alpha, Baz) private , 我得到一个 FooTest 的编译错误,说明:

Error:(10, 12) java: bar(Xray,Baz) has private access in Foo

有没有办法使用 PowerMockito 解决这个问题?如何?(显然,我只想计算对 bar(Xray, Baz) 的调用 - 计算对 bar() 的所有重载的所有调用是不可能的......)

仅使用 eq(xray)而不是 any(Xray.class)在测试的第 10 行和第 14 行可以解决问题 - 但我对 什么 并不感兴趣(具体)Xray 对象作为参数传递给 bar() ,只要它是任何 Xray对象...

更新:我发布了 separate question对于讨论的“PowerMockito 和 private 方法”部分,并弄清楚如何使这项工作适用于 public方法;比照。我的comment below .

最佳答案

你不需要这样做。

这让您抓狂的原因是您没有按照预期的方式使用 Mockito。它可以以这种方式使用,但不应该这样。

您不需要测试是否调用了正确的方法,您需要测试类的行为是否正确。这是什么意思?

  1. 您想检查是否返回了 “Xray”

    String result = foo.bar(alpha, baz);
    assertEquals("Xray", result);
  2. 您想检查是否调用了 Alpha.get。如果有的话,这意味着 Alpha 应该是 stub ,而不是 Foo

    Alpha alpha = spy(new Alpha());
    String result = foo.bar(alpha, baz);
    verify(alpha).get();

底线是这样的:您有被测系统,在本例中为 Foo。该类应该是真实类您的模拟和 stub 应该是与 Foo 交互的其他对象;验证交互做正确的事情

换句话说,您不应该测试如何 Foo 工作,您应该测试那个 Foo 做它应该做的事;结果是正确的。

关于java - 如何使用 Mockito 验证重载方法的调用次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32206315/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com