1

假设我们有

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方法?

以前的技巧 withreplace(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: Unexpected method call bar.

那么我该怎么做呢?我不想将嘲笑.bar(...)放入,因为在现实世界中,我需要一些静态方法getMockInstance中不可用的数据。getMockInstance

4

1 回答 1

3

我认为问题在于您在foo模拟上调用了两次重播,一次是在模拟的静态方法中getMockInstance(),一次是在您告诉模拟foo期望foo.bar(bar1)调用之后。尝试更改getMockInstance()

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

然后告诉 EasyMockfoo在你告诉它期待bar方法调用之后重播。所以 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;
   }
于 2011-02-02T13:35:57.607 回答