Reputation: 3065
I'm trying to use Mockito to test a settings manager which saves data through SharedPreferences
.
Since SharedPreferences
makes use of Context
, I need to use mock classes.
This is my settings manager class:
public class SettingsManager implements ISettingsManager {
protected SharedPreferences prefs;
public SettingsManager(SharedPreferences prefs) {
this.prefs = prefs;
}
private boolean getBooleanPreference(String key) {
return prefs.getBoolean(key, true);
}
private void setBooleanPreference(boolean enabled, String key) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(key, enabled);
editor.commit();
}
}
This is the test case I wrote:
Context mContext = Mockito.mock(Context.class);
SharedPreferences mSharedPreference = Mockito.mock(SharedPreferences.class);
SharedPreferences.Editor mEditor = Mockito.mock(SharedPreferences.Editor.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(mSharedPreference.edit()).thenReturn(mEditor);
Mockito.when(mEditor.commit()).thenReturn(true);
Mockito.when(mEditor.putBoolean(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(mEditor);
SettingsManager manager = new SettingsManager(mSharedPreference);
boolean current = manager.areNotificationsEnabled();
manager.setNotificationsEnabled(!current);
boolean newValue = manager.areNotificationsEnabled();
Assert.assertTrue(newValue != current);
The problem is when I set the setNotificationsEnabled
flag, the newValue
remains the same of current
: SharedPreferences
does not persist data. How can I save data to SharedPreferences
while testing?
Upvotes: 1
Views: 1347
Reputation: 21487
Robolectric is an option for this kind of integration test.
Robolectric provides test doubles called "shadows" of common Android classes like Context
, SQLiteDatabase
and SharedPreferences
. The tests you write run in test
in your IDE (not androidTest
on an emulator or test device) so it is easier to configure tools for test coverage.
The shadow SharedPreference
is sandboxed as well so it won't interfere with the actual SharedPreferences
on a device.
Upvotes: 3
Reputation: 159
Convert this to an AndroidTest and use InstrumentationRegistry.getTargetContext()
to get a context, this way you can use the class without mocking it
Upvotes: 2