我可以使用 doReturn 将 returns 与 PowerMockito 链接起来吗?
Can I chain returns with PowerMockito using doReturn?
我有一个方法调用,第一次调用时需要 return valueA,第二次调用时需要 valueB。我正在使用 PowerMockito 间谍,所以如果我只需要 return 一个值,它看起来像这样:
PowerMockito.doReturn(valueA).when(mockedObject, "methodName");
看来我可以像这样链接 returns:
PowerMockito.when(mockedObject, "methodName").thenReturn(valueA).thenReturn(valueB);
但我需要用 doReturn 指示链式 returns 以便真正的 methodName() 不会在我的 Spy 上调用。
我试过了,但 Eclipse 给我一个错误,说它甚至无法编译:
PowerMockito.doReturn(valueA).doReturn(valueB).when(mockedObject, "methodName");
甚至可以用 doReturn 和 powermockito 链接 returns 吗?如果可以,怎么做?
我不这么认为。相反,您可以使用如下所示的 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
(等)将 return 变成 PowerMockitoStubber implementation, which extends Mockito's Stubber; under the hood, PowerMockitoStubberImpl extends StubberImpl。因为 PowerMock 不需要更改功能,所以它不会覆盖这些调用; PowerMockito.doReturn(foo).doReturn(bar)
中的第二个 doReturn
将调用 Mockito 的 StubberImpl 和 return 一个 Mockito Stubber。
这是个问题,因为在过渡到 Stubber 时,您会丢失 PowerMockito when
签名,例如您需要的签名。 简而言之,PowerMockito doVerb
调用支持链接,并且支持反射式或按名称引用方法,但目前不能同时使用。
在内部,StubberImpl 遵循构建器模式,return在每次调用后自动运行:
public Stubber doCallRealMethod() {
answers.add(new CallsRealMethods());
return this;
}
因为 this
指的是 PowerMockitoStubberImpl
子类,所以很容易 将 Stubber 转换为 PowerMockitoStubber 以访问其他方法。对于上述解决方法,您自己进行转换:
((PowerMockitoStubber) PowerMockito.doReturn(valueA).doReturn(valueB))
.when(mockedObject, "methodName");
作为长期解决方案,因为任何 returns PowerMockitoStubber 必然 returns Stubber,这可能会为所有 PowerMockito 用户修复纯粹通过接口覆盖(注意 caveats listed on Joseph D. Darcy's Oracle Weblog)。我还没有测试过这个,但这可能很简单:
/* in PowerMockitoStubber.java, for each doVerb method: */
@Override public PowerMockitoStubber doNothing();
此时您只需调整 return 类型:
@Override public PowerMockitoStubber doNothing() {
super.doNothing();
return this;
}
从 PowerMock v1.6.5 开始,您可以将多个值传递给 doReturn(Object toBeReturned, Object... othersToBeReturned)。
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 value, T... values) 相同:在调用方法时定义连续的 return 个值 - 最后一个决定进一步调用的行为。
我有一个方法调用,第一次调用时需要 return valueA,第二次调用时需要 valueB。我正在使用 PowerMockito 间谍,所以如果我只需要 return 一个值,它看起来像这样:
PowerMockito.doReturn(valueA).when(mockedObject, "methodName");
看来我可以像这样链接 returns:
PowerMockito.when(mockedObject, "methodName").thenReturn(valueA).thenReturn(valueB);
但我需要用 doReturn 指示链式 returns 以便真正的 methodName() 不会在我的 Spy 上调用。
我试过了,但 Eclipse 给我一个错误,说它甚至无法编译:
PowerMockito.doReturn(valueA).doReturn(valueB).when(mockedObject, "methodName");
甚至可以用 doReturn 和 powermockito 链接 returns 吗?如果可以,怎么做?
我不这么认为。相反,您可以使用如下所示的 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
(等)将 return 变成 PowerMockitoStubber implementation, which extends Mockito's Stubber; under the hood, PowerMockitoStubberImpl extends StubberImpl。因为 PowerMock 不需要更改功能,所以它不会覆盖这些调用; PowerMockito.doReturn(foo).doReturn(bar)
中的第二个 doReturn
将调用 Mockito 的 StubberImpl 和 return 一个 Mockito Stubber。
这是个问题,因为在过渡到 Stubber 时,您会丢失 PowerMockito when
签名,例如您需要的签名。 简而言之,PowerMockito doVerb
调用支持链接,并且支持反射式或按名称引用方法,但目前不能同时使用。
在内部,StubberImpl 遵循构建器模式,return在每次调用后自动运行:
public Stubber doCallRealMethod() {
answers.add(new CallsRealMethods());
return this;
}
因为 this
指的是 PowerMockitoStubberImpl
子类,所以很容易 将 Stubber 转换为 PowerMockitoStubber 以访问其他方法。对于上述解决方法,您自己进行转换:
((PowerMockitoStubber) PowerMockito.doReturn(valueA).doReturn(valueB))
.when(mockedObject, "methodName");
作为长期解决方案,因为任何 returns PowerMockitoStubber 必然 returns Stubber,这可能会为所有 PowerMockito 用户修复纯粹通过接口覆盖(注意 caveats listed on Joseph D. Darcy's Oracle Weblog)。我还没有测试过这个,但这可能很简单:
/* in PowerMockitoStubber.java, for each doVerb method: */
@Override public PowerMockitoStubber doNothing();
此时您只需调整 return 类型:
@Override public PowerMockitoStubber doNothing() {
super.doNothing();
return this;
}
从 PowerMock v1.6.5 开始,您可以将多个值传递给 doReturn(Object toBeReturned, Object... othersToBeReturned)。
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 value, T... values) 相同:在调用方法时定义连续的 return 个值 - 最后一个决定进一步调用的行为。