我是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);
}
}
您能否就如何解决此错误给我一些指导?
答案 0 :(得分:2)
不是直接引用Android SDK,而是从您的演示者逻辑中抽象出来。这意味着,不是执行PreferenceManager.getDefaultSharedPreferences()
,而是创建抽象并从抽象中请求territoryString
。
这会给你带来什么,是你的主持人不知道来自Android SDK的PreferenceManager
和SharedPreferences
的前置,因此你会有足够的接缝来进行纯单元测试。
说完这个,让我们实现抽象。声明了以下界面:
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);
}
}
然后你的主持人就会变成这样:
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
。