我是 Android 单元测试的新手,我想在现有项目中添加一些单元测试。我正在使用 MVP 设计架构。在我的演示者中,我调用了 PreferenceManager
以获得默认的 SharedPrefences
但它始终返回 null。我在 stackoverflow 上遵循了一些关于如何模拟 PreferenceManager
和 SharedPreferences
的教程和建议,但我无法让它工作。这是我的主讲类
@RunWith(MockitoJUnitRunner.class)
public class SettingsPresenterTest {
@Mock
private SettingsView mView;
@Mock
private LocalConfiguration conf;
private SettingsPresenter mPresenter;
public SettingsPresenterTest() {
super();
}
@Before
public void startUp() throws Exception {
MockitoAnnotations.initMocks(LocalConfiguration.class);
MockitoAnnotations.initMocks(PreferenceManager.class);
mPresenter = new SettingsPresenter(mView);
final SharedPreferences sharedPrefs =
Mockito.mock(SharedPreferences.class);
final Context context = Mockito.mock(Context.class);
Mockito.when(PreferenceManager.getDefaultSharedPreferences(context)).
thenReturn(sharedPrefs);
}
@Test
public void notificationsEnabledClicked() throws Exception {
boolean notifsEnabled = false;
mPresenter.notificationsEnabledClicked(notifsEnabled);
Mockito.verify(mView).setNotificationsView(notifsEnabled);
}
}
这里是 SharedPreferences
返回 null 的方法
public class LocalConfiguration {
public TerritoryDto getLastSavedTerritory() {
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(H.getContext());
String terrritoryString = preferences.getString(SAVED_TERRITORY,
null);
return
SerializerHelper.getInstance().deserialize(terrritoryString,
TerritoryDto.class);
}
}
你能给我一些关于如何解决这个错误的指南吗?
最佳答案
与其直接引用 Android SDK,不如从您的呈现器逻辑中抽象出来。这意味着,不是执行 PreferenceManager.getDefaultSharedPreferences()
,而是创建一个抽象并从您的抽象中请求 territoryString
。
这会给你带来什么,你的演示者不会知道来自 Android SDK 的 PreferenceManager
和 SharedPreferences
的precense,因此你会有足够的接缝来执行纯单元测试。
说到这里,让我们来实现抽象。声明了以下接口(interface):
public interface Storage {
@Nullable
String getSavedTerritory();
}
具体实现是:
public SharedPrefsStorage implements Storage {
private final SharedPreferences prefs;
public SharedPrefsStorage(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences();
}
@Nullable
@Override
public String getSavedTerritory() {
return prefs.getString(SAVED_TERRITORY, null);
}
}
那么你的presenter会变成这样:
public class LocalConfiguration {
final Storage storage;
public LocalConfiguration(Storage storage) {
this.storage = storage;
}
public TerritoryDto getLastSavedTerritory() {
final String territory = storage.getSavedTerritory();
return SerializerHelper.getInstance().deserialize(territory, TerritoryDto.class);
}
}
这会给你一个接缝来执行纯单元测试:
@Test
void someTest() {
when(storage.getSavedTerritory()).thenReturn("New York");
...
}
再也不用担心模拟 PreferenceManager
了。
关于android - 使用 Mockito 模拟 PreferenceManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46886351/