使用PowerMock模拟一个单例的getInstance



我有下面的Singleton,它返回一个不同类的实例。我想模拟返回的实例对象上的方法。我一直在阅读PowerMock对final类和单例的mock特性,但我不知道我的情况是否属于这些。我很感激你的建议。

public final class SomeWrapper {
    private MyActualObject MyActualObject;
    private static final SomeWrapper instance = new SomeWrapper();
    private SomeWrapper() {
        // singleton
    }
    public static SomeWrapper getInstance() {
        return instance;
    }
    public void setMyActualObject(MyActualObject MyActualObject) {
        if(this.MyActualObject == null) {
            this.MyActualObject = MyActualObject;
        } else {
            throw new UnsupportedOperationException("MyActualObject is already set, cannot reset.");
        }
    }
    public MyActualObject getMyActualObject() {
        return MyActualObject;
    }
}

现在在我的单元测试中,我想模拟下面这行:

when(SomeWrapper.getInstance().getMyActualObject().isActive()).thenReturn(false);

我应该模拟SomeWrapper和MyActualObject吗?任何代码示例作为指导?

使用这些Mockito &PowerMock版本:

testImplementation 'org.mockito:mockito-core:2.23.4'
testImplementation 'org.powermock:powermock-module-junit4:2.0.0-beta.5'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.0-beta.5'

您可以使用PowerMock.mockStatic()when()机制模拟android MainApplication的单例实例(例如),像这样:

private MainApplication mApplication;
@NonNull
protected MainApplication getApplication() {
    if (mApplication == null) {
        mApplication = PowerMockito.mock(MainApplication.class);
        PowerMockito.mockStatic(MainApplication.class);
        PowerMockito.when(MainApplication.getInstance()).thenReturn(mApplication);
        PowerMockito.when(mApplication.getBaseContext()).thenReturn(mApplication);
        PowerMockito.when(mApplication.getApplicationContext()).thenReturn(mApplication);
    }
    return mApplication;
}

模拟私有构造函数可能是棘手的-你可以尝试在这篇文章中建议的方法,通过在thenReturn()调用中使用替代类:SO - mock私有构造函数

关键是:您编写了难以测试的代码。是的,PowerMock可以帮助"修复"这个问题,但是您可能更喜欢简单地重做您的产品代码,使其更容易测试。

例如,通过添加一个包保护构造函数,如:
SomeWrapper(MyActualObject myActualObject) {
  this.MyActualObject = myActualObject;
}

这将允许您创建一个SomeWrapper类的实例,该实例接收一个完全有效的MyActualObject实例。

在这个意义上:你可能想学习如何创建实际可测试的产品代码。

相关内容

  • 没有找到相关文章

最新更新