我有下面的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实例。
在这个意义上:你可能想学习如何创建实际可测试的产品代码。