无法使用Powermock模拟静态方法(使用EasyMock)

时间:2013-02-05 10:05:59

标签: unit-testing junit mocking easymock powermock

我想模拟静态方法以及类的非静态方法。   我的来源看起来像:

    public class XDSUtilityManager
    {
private static XDSUtilityManager xdsUtilMgr = new XDSUtilityManager(); private XDSUtilityManager() { xdsUtilMgrImpl = new XDSUtilityManagerImpl(); }
public static XDSUtilityManager getInstance() { return (xdsUtilMgr == null ) ? new XDSUtilityManager() : xdsUtilMgr; } public XMLDocument getXMLDocument(final String absoluteKey, final XDSClient xdsClient) { return getXMLDocument(absoluteKey, xdsClient, false); } }

我想模拟静态方法 getInstance()。我希望getInstance()返回 XDSUtilityManager 类的模拟对象。另外我想模拟 getXMLDocument(),这不是静态的。

在我的testCase中,我尝试了以下内容:

XMLDocument xmlDocument = PowerMock.createMock(XMLDocument.class);
XDSUtilityManager xdsUtilityManager = PowerMock.createPartialMock(XDSUtilityManager.class,"getXMLDocument");
PowerMock.mockStaticPartial(XDSUtilityManager.class, "getInstance"); expect(XDSUtilityManager.getInstance()).andReturn(xdsUtilityManager).anyTimes();
expect(xdsUtilityManager.getXMLDocument((String)anyObject(), anyObject(XDSClient.class))).andReturn(xmlDocument).anyTimes();
PowerMock.replay(xdsUtilityManager); PowerMock.replay(xmlDocument);

但事情没有按预期发挥作用。请帮忙

2 个答案:

答案 0 :(得分:7)

我发现这样做的最简单方法是使用PowerMockito。 PowerMockito是Mockito和PowerMock的组合,它允许模拟静态对象。

我使用的模式是使用mock你的静态getInstance()来返回非静态模拟的副本,然后你可以正常扩展。使用PowerMockito的示例如下:

@RunWith(PowerMockRunner.class)
@PrepareForTest({SingletonObject.class})
public class SingletonTester {
  @Mock
  private SingletonObject singleMock;

  @Before
  public void setup(){
      // initialize all the @Mock objects
      MockitoAnnotations.initMocks(this);
      // mock all the statics
      PowerMockito.mockStatic(SingletonObject.class);
  }

  @Test
  public void mockTester(){
      // Mock the static getInstance call to return the non-Static Mock
      Mockito.when(SingletonObject.getInstance()).thenReturn(singleMock);

      // Mock the non static version as normal
      PowerMockito.when(singleMock.nonStaticMethodCall()).thenReturn("Whatever you need.");
      //..........
  }
}

getInstance()的静态调用以获取singleton对象将返回您也定义的实例化模拟对象。一旦告诉静态返回什么,就可以继续正常模拟非静态调用。

答案 1 :(得分:1)

不需要调用getInstance()方法来创建XDSUtilityManager的实例。 使用PowerMockito,因为您的构造函数是私有的,所以在调用create mock之前需要suppress the constructor,如下所示。

PowerMockito.suppress(PowerMockito.constructor(XDSUtilityManager.class));
// enable static mocking for all the methods in the class   
PowerMockito.mockStatic(XDSUtilityManager.class); 
XDSUtilityManager xDSUtilityManager =  PowerMockito.mock(XDSUtilityManager.class);
XMLDocument xmlDocument = PowerMock.createMock(XMLDocument.class); 
PowerMockito.when(xDSUtilityManager.getXMLDocument(
    Mockito.anyString(),Mockito.anyObject())).thenReturn(xmlDocument);