简体   繁体   English

使用PowerMock模拟静态和动态方法

[英]Mocking both static and dynamic methods with PowerMock

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 . 我需要模拟Foo类的静态和动态方法。 Mocking getInstance() is as easy as 模拟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;
   }
}

The question is, how to mock bar method? 问题是,如何模拟bar方法?

Previous trick with replace(method(...)).with(method(...)) does not work as it is not designed for dynamic methods. 以前使用replace(method(...)).with(method(...))技巧不起作用,因为它不是为动态方法设计的。

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 . 上面的代码抛出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. 我不想将.bar(...)getMockInstance放到getMockInstance因为在现实世界中,我需要一些静态getMockInstance方法中不可用的数据。

I think the issue is that you are calling replay on your foo mock twice, once in the mocked static method getMockInstance() and once after you tell mocked foo to expect the foo.bar(bar1) call. 我认为问题在于您在foo模拟上调用了两次重播,一次是在模拟的静态方法getMockInstance() ,一次是在告诉foo.bar(bar1) foo期待foo.bar(bar1)调用之后。 Try altering the getMockInstance() to 尝试将getMockInstance()更改为

   public static Foo getMockInstance() {
      Foo foo = EasyMock.createMock(Foo.class);
      return foo;
   }

and then telling EasyMock to replay foo after you tell it to expect the bar method call. 然后告诉EasyMock期望bar方法调用后重播foo So the MyTest.java would look something like this: 所以MyTest.java看起来像这样:

@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);
}

  public static Foo getMockInstance() {
      Foo foo = EasyMock.createMock(Foo.class);
      return foo;
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM