部分模拟非静态方法不会在其中调用私有静态方法

时间:2017-07-28 23:35:55

标签: java unit-testing powermock

我正在使用Powermock为我的一个方法编写测试用例,如下所示:

class A{
  static String hello = "hello";
  private void static init(String s){
      hello = hello+" "+s;
  }
  public String getString(String s){
      init(s);
      return hello;
 }
}

class B{
    A a = new A();
    public String printHelloWorld(){            
        return a.getString("World")+" from Hawaii";     
    }
}

我试图通过使用PowerMock模拟类A的方法getString来测试类B的getStringFromA方法,如下所示:

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
class TestClass{
  @Test
  public void testMethod(){

      //Mock Creation
      A dummy = createPartialMock(A.class,"getString",String.class);

     //Expect
     expectNew(A.class).andReturn(dummy);
     expect(dummy.getString("World")).andReturn("Hello World");

     //Replay
     replayAll();

     //Execute
     B b = new B();
     b.printHelloWorld();
  }
}  

问题是这似乎不起作用。类A的getString()方法不执行私有静态方法init()。我认为这是因为我们正在嘲笑方法getString()。但是,如果方法getString()也是静态执行转到init方法。 这可能是造成这种异常现象的原因。

谢谢, 玛纳斯

1 个答案:

答案 0 :(得分:0)

完全按预期工作。来自documentation

  

PowerMock.createPartialMock(ClassToPartiallyMock.class,“nameOfTheFirstMethodToMock”,“nameOfTheSecondMethodToMock”)创建一个模拟对象,该对象仅使用名称nameOfTheFirstMethodToMock ...

来模拟方法

指示 PowerMock 模拟 getString()。模拟意味着:它是一个假人,而不是任何东西

从这个意义上讲:你应该退后一步,阅读 如何使用模拟来进行适当的单元测试。您甚至不清楚是否要测试A类或B类。

你看,为了测试B类,你不需要PowerMock或部分模拟。你只需要这样做:

A mockedA = mock(A.class);
when(mockedA.getString("foo")).thenReturn("bar");

B underTest = new B(mockedA);
assertThat(b.printHelloWorld(), is("bar from hawaii"));

或类似的东西。以上是使用Mockito调用,但EasyMock没有太大的不同。

重点是:只需提供 A类到B类的实例,而不是在B类中执行new,并且您对增强模拟功能的所有需求都会完全消失。

换句话说:这里不需要部分嘲弄。即使您想要进行部分嘲弄 - 请仔细阅读文档。所有这些都是完全记录。