phe*_*aal 4 java junit easymock powermock
这可能是一个PowerMock/EasyMock 101问题,我无法弄清楚为什么.我有一个C类方法
public static boolean testInner(String s) {
return false;
}
public static boolean testOuter() {
String x = "someValue";
return testInner(x);
}
Run Code Online (Sandbox Code Playgroud)
在我的testOuter()方法测试中,我想确保使用适当的参数调用testInner.为此,我正在做这样的事情:[@RunWith(PowerMockRunner.class)@PrepareForTest(EmailUtil.class)在Class级别声明]
EasyMock.expect(C.testInner("blabla")).andReturn(true);
PowerMock.replayAll();
boolean status = C.testOuter();
PowerMock.verifyAll();
assertTrue(status);
Run Code Online (Sandbox Code Playgroud)
但我得到的错误是:
java.lang.AssertionError:
Unexpected method call testOuter():
testInner("blabla"): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:95)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:60)
at C.testOuter(C.java)
Run Code Online (Sandbox Code Playgroud)
我用EasyMock.IsA(String.class)替换了实际参数,但仍然没有运气.我很确定我在做一些从根本上说是愚蠢的事情.有帮助吗?
rru*_*fai 13
我认为这里有两个问题,一个与你的测试代码中缺少调用有关.第二个与你对行为嘲弄的理解以及完全和部分嘲弄之间的区别有关.
你似乎错过了一个调用方法PowerMock.mockStatic或其中一个PowerMock.mockPartialMock方法(另见这个).第一种方法将模拟传递给它的所有静态方法,而第二种方法将仅模拟它给出的方法列表.
这是一个完整的示例,其中包含两个测试方法,说明了这两个选项.首先,我们必须使用这两个注释来注释测试类:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Dummy.class)
public class DummyTest {
Run Code Online (Sandbox Code Playgroud)
第一个注释告诉JUnit使用PowerMockRunner运行测试.第二个注释告诉PowerMock准备模拟Dummy类.
接下来,我们将看一个示例,其中Dummy模拟了类中的所有静态方法.这是什么意思?这基本上意味着我们想用假的(模拟)替换实际的实现.这个假实现应该如何表现?这是我们在期望中指定的内容.
因此,在该testStaticMock方法中,我们告诉EasyMock给我们两个方法的假实现.我们会喜欢假Dummy.testOuter的简单回归true.我们会喜欢假的Dummy.testInner true在传递参数时返回"bb".请注意,当这些模拟被激活(PowerMock.replayAll)时,测试代码将只运行假方法而不是实际实现 - 这似乎是您混淆的根源.我稍后会对此发表更多意见.
@Test
public void testStaticMock() {
mockStatic(Dummy.class);
EasyMock.expect(Dummy.testOuter()).andReturn(true);
EasyMock.expect(Dummy.testInner("bb")).andReturn(true);
replayAll();
boolean status = Dummy.testOuter();
Assert.assertTrue(status);
status = Dummy.testInner("bb");
Assert.assertTrue(status);
verifyAll();
}
Run Code Online (Sandbox Code Playgroud)
这是另一个测试,我们不会模拟所有方法,只模拟我们传递给的方法mockStaticPartial.下面,我们告诉PowerMock我们只想模拟该方法Dummy.testInner.因此,部分Dummy被嘲笑,其余部分被测试.
@Test
public void testPartialStaticMock() {
mockStaticPartial(Dummy.class, "testInner");
EasyMock.expect(Dummy.testInner("someValue")).andReturn(true);
replayAll();
boolean status = Dummy.testOuter();
verifyAll();
Assert.assertTrue(status);
}
}
Run Code Online (Sandbox Code Playgroud)
让模拟类Dummy定义如下:
public class Dummy {
public static boolean testInner(String s) {
return false;
}
public static boolean testOuter() {
String x = "someValue";
return testInner(x);
}
}
Run Code Online (Sandbox Code Playgroud)
关于完全静态模拟的一件事是,所有静态方法都被模拟.因此,该方法testOuter将被模拟版本替换,将具有如下实现:
public static boolean testOuter() {
return true; //or whatever value is provided in the expectation
}
Run Code Online (Sandbox Code Playgroud)
因此,我们不应期望模拟版本调用实际实现的方法.我们不想关心该方法的内部.这就是原因,我们决定无论如何都要嘲笑它 - 用玩具实现取代它的内部结构,只能按照我们为它设定的期望来定义.
另一方面,当我们进行部分模拟时testOuter,我们没有模拟,所以我们调用了它的实际实现.
| 归档时间: |
|
| 查看次数: |
19711 次 |
| 最近记录: |