使用 PowerMock 模拟静态和动态方法
假设我们有
public class Foo {
public static Foo getInstance() {...}
public Bar bar(Baz baz) {...}
}
我想做的就是在我的单元测试中模拟它。我需要模拟 Foo 类的静态和动态方法。模拟 getInstance()
就像简单的
import static org.powermock.api.easymock.PowerMock.replace;
import static org.powermock.api.easymock.PowerMock.method;
public class MyTest {
@Test
public void myTest() {
replace(method(Foo.class, "getInstance"))
.with(method(MyTest.class, "getMockInstance"));
}
public static Foo getMockInstance() {
Foo foo = EasyMock.createMock(Foo.class);
EasyMock.replay(foo);
return foo;
}
}
问题是,如何模拟 bar
方法?
之前使用 replace(method(...)).with(method(...))
的技巧不起作用,因为它不是为动态方法设计的。
尝试在已经模拟的类之上进行模拟也不起作用:
...
@Test
public void myTest() {
replace(method(Foo.class, "getInstance"))
.with(method(MyTest.class, "getMockInstance"));
Foo foo = Foo.getInstance(); // works well
Baz baz1 = new Baz();
Baz baz2 = new Baz();
EasyMock.expect(foo.bar(baz1)).andReturn(baz2); // exception thrown
EasyMock.replay(foo);
}
...
上面的代码会抛出AssertionError:意外的方法调用栏
。
那么我该如何做到这两点呢?我不想将 .bar(...)
的模拟放入 getMockInstance
中,因为在现实世界中,我需要一些静态<代码>中无法获得的数据。代码>getMockInstance方法。
Let's say we have
public class Foo {
public static Foo getInstance() {...}
public Bar bar(Baz baz) {...}
}
What I want to do is to mock it in my unit tests. I need to mock both static and dynamic methods of a class Foo
. Mocking getInstance()
is as easy as
import static org.powermock.api.easymock.PowerMock.replace;
import static org.powermock.api.easymock.PowerMock.method;
public class MyTest {
@Test
public void myTest() {
replace(method(Foo.class, "getInstance"))
.with(method(MyTest.class, "getMockInstance"));
}
public static Foo getMockInstance() {
Foo foo = EasyMock.createMock(Foo.class);
EasyMock.replay(foo);
return foo;
}
}
The question is, how to mock bar
method?
Previous trick with replace(method(...)).with(method(...))
does not work as it is not designed for dynamic methods.
Trying to mock on top of already mocked class also doesn't work:
...
@Test
public void myTest() {
replace(method(Foo.class, "getInstance"))
.with(method(MyTest.class, "getMockInstance"));
Foo foo = Foo.getInstance(); // works well
Baz baz1 = new Baz();
Baz baz2 = new Baz();
EasyMock.expect(foo.bar(baz1)).andReturn(baz2); // exception thrown
EasyMock.replay(foo);
}
...
Code above throws AssertionError: Unexpected method call bar
.
So how do I do both? I don't want to put mocking of .bar(...)
into the getMockInstance
because in the real world I need some data that is not available from within static getMockInstance
method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为问题在于您在
foo
模拟上调用重播两次,一次在模拟静态方法getMockInstance()
中,一次在您告诉模拟foo< /code> 期待
foo.bar(bar1)
调用。尝试将getMockInstance()
更改为,然后告诉 EasyMock 在等待
bar
方法调用后重播foo
。所以 MyTest.java 看起来像这样:I think the issue is that you are calling replay on your
foo
mock twice, once in the mocked static methodgetMockInstance()
and once after you tell mockedfoo
to expect thefoo.bar(bar1)
call. Try altering thegetMockInstance()
toand then telling EasyMock to replay
foo
after you tell it to expect thebar
method call. So the MyTest.java would look something like this: