使用PowerMock模拟单例的getInstance

问题描述 投票:2回答:2

我有以下Singleton返回不同类的实例。我想在返回的实例对象上模拟方法。我一直在阅读有关最终课程和单身人士的PowerMock模拟功能,但我不知道我的案例是否属于这些。我很欣赏一些建议。

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吗?任何代码示例作为指导?

java unit-testing mockito powermock easymock
2个回答
1
投票

这里的要点是:你编写了难以测试的代码。是的,PowerMock可以帮助“修复”它,但您可能更愿意简单地重新编写生产代码,以便更容易测试。

例如,通过添加包受保护的构造函数,例如:

SomeWrapper(MyActualObject myActualObject) {
  this.MyActualObject = myActualObject;
}

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

从这个意义上说:您可能想学习如何创建实际上是testable的生产代码。


0
投票

使用这些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'

你可以使用MainApplicationPowerMock.mockStatic()机制模拟一个android when()单例实例(例如),如下所示:

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 - Mocking Private Constructor

© www.soinside.com 2019 - 2024. All rights reserved.