>我有一个方法调用,第一次调用时需要返回值A,第二次调用时需要返回值B。 我正在使用PowerMockito间谍,所以如果我只需要返回一个值,它将如下所示:
PowerMockito.doReturn(valueA).when(mockedObject, "methodName");
看起来我可以像这样做链式返回:
PowerMockito.when(mockedObject, "methodName").thenReturn(valueA).thenReturn(valueB);
但是我需要用doReturn指示链式返回,这样就不会在我的间谍上调用真正的methodName((。
我已经尝试过这个,但是Eclipse给了我一个错误,说它甚至无法编译:
PowerMockito.doReturn(valueA).doReturn(valueB).when(mockedObject, "methodName");
甚至有可能将回报与doReturn和powermockito联系起来吗? 如果是这样,如何?
从 PowerMock v1.6.5 开始,您可以将多个值传递给 doReturn(Object toBeReturn, Object...其他要返回(。
private static class Example {
public String getValue() {
return null;
}
}
@Test
public void testReturnChain() throws Exception {
Example example = new Example();
Example mockExample = PowerMockito.spy(example);
PowerMockito.doReturn("firstValue", "secondValue").when(mockExample, "getValue");
assertEquals("firstValue", mockExample.getValue());
assertEquals("secondValue", mockExample.getValue());
assertEquals("secondValue", mockExample.getValue());
}
行为与 thenReturn(T 值,T... 值(相同:在调用方法时定义连续的返回值 - 最后一个确定进一步调用的行为。
我不这么认为。相反,您可以使用doAnswer和Queue来实现它,如下所示。
@Test
public void testReturnChain() throws Exception {
Example example = new Example() {
public String getValue() {
return null;
}
};
Example mockExample = spy(example);
PowerMockito.doAnswer(new Answer<String>() {
private final Queue<String> values = new LinkedList<String>(Arrays.asList("firstValue", "secondValue"));
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return values.poll();
}
}).when(mockExample, "getValue");
System.out.println(mockExample.getValue());
System.out.println(mockExample.getValue());
System.out.println(mockExample.getValue());
}
试试这个:
((PowerMockitoStubber) PowerMockito.doReturn(valueA).doReturn(valueB))
.when(mockedObject, "methodName");
简而言之,我认为您已经在PowerMockito API中发现了一个漏洞。作为拉取请求提交,或者至少作为功能请求提交,这可能是一件好事。
正在发生的事情是,org.powermock.api.mockito.PowerMockito.doReturn
(等人(将返回一个PowerMockitoStubber实现,它扩展了Mockito的Stubber;在引擎盖下,PowerMockitoStubberImpl扩展了StubberImpl。由于 PowerMock 不需要更改功能,因此它不会重写这些调用;PowerMockito.doReturn(foo).doReturn(bar)
中的第二个doReturn
将调用 Mockito 的 StubberImpl 并返回一个 Mockito Stubber。
这是一个问题,因为在过渡到 Stubber 的过程中,您会丢失 PowerMockito when
签名,例如您需要的签名。简而言之,PowerMockito doVerb
调用确实支持链接,并且支持以反射方式或按名称引用方法,但目前不能同时引用两者。
在内部,StubberImpl遵循构建器模式,在每次调用后返回自身:
public Stubber doCallRealMethod() {
answers.add(new CallsRealMethods());
return this;
}
由于this
引用PowerMockitoStubberImpl
子类,因此很容易将 Stubber 强制转换为 PowerMockitoStubber 以访问其他方法。对于上述解决方法,您自己制作强制转换:
((PowerMockitoStubber) PowerMockito.doReturn(valueA).doReturn(valueB))
.when(mockedObject, "methodName");
作为一个长期的解决方案,因为任何返回PowerMockitoStubber的东西都必须返回Stubber,所以可以纯粹通过接口覆盖为所有PowerMockito用户修复这个问题(注意Joseph D. Darcy的Oracle博客上列出的警告(。我还没有测试过这个,但它可能很容易:
/* in PowerMockitoStubber.java, for each doVerb method: */
@Override public PowerMockitoStubber doNothing();
此时,您只需调整返回类型:
@Override public PowerMockitoStubber doNothing() {
super.doNothing();
return this;
}