Reputation: 118
I am trying to write unit tests by mocking Android Shared preference using Mockito Library, however it doesn't work for me even after multiple tries. Please check my sample code below and let me know what went wrong with it
I am currently using "JCAndKSolutions/android-unit-test" android junit plug-in.
My code is as below:
PreferenceHelper.java
public class PreferencesHelper
{
private SharedPreferences mSharedPreferences;
static String PREFERENCE_USER;
public PreferencesHelper(SharedPreferences mSharedPreferences)
{
this.mSharedPreferences = mSharedPreferences;
}
public void setUserName(String userName)
{
mSharedPreferences.edit().putString(PREFERENCE_USER, "Vkc").apply();
}
public String getUserName()
{
return mSharedPreferences.getString(PREFERENCE_USER, null);
}
}
PreferenceHelperTest.java
public class PreferencesHelperTest extends TestCase
{
@Mock
SharedPreferences mSharedPreference;
@Mock
SharedPreferences.Editor mEditor;
@Mock
Context context;
@Mock
PreferenceManager mPreferenceManager;
PreferencesHelper mPrefHelper;
public void setUp() throws Exception
{
initMocks(this);
}
public void testSetUserName(){
final InOrder inOrder = inOrder(mEditor);
when(mSharedPreference.edit()).thenReturn(mEditor);
mPrefHelper = new PreferencesHelper(mSharedPreference);
mPrefHelper.setUserName("Grapes");
inOrder.verify(mEditor).putString(PreferencesHelper.PREFERENCE_USER, "Grapes");
inOrder.verify(mEditor).apply();
}
}
If I run this junit test I get following error
java.lang.NullPointerException
at com.example.aag.testhelloworld.PreferencesHelper.setUserName(PreferencesHelper.java:21)
at com.example.aag.testhelloworld.PreferencesHelperTest.testSetUserName(PreferencesHelperTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
While debugging I found that when putString() method is invoked nullPointer exception is thrown.
Any help or clues where it went wrong??
Upvotes: 2
Views: 8082
Reputation: 1005
This is working for me...
public MainPresenter(final MainView view, SharedPreferences sp) {
this.view = view;
this.sp = sp;
}
public void saveToSharedPref(String key,int value){
SharedPreferences.Editor editor = sp.edit();
editor.putInt(key,value);
}
//Tests
@Mock
MainPresenter.MainView view;
@Mock
SharedPreferences sp;
@Mock
SharedPreferences.Editor editor;
@Before
public void setup(){
view = mock(MainPresenter.MainView.class);
sp = mock(SharedPreferences.class);
editor = mock(SharedPreferences.Editor.class);
presenter = new MainPresenter(view, sp);
}
@Test
public void saveToSharedPref_withValidKeyAndValue_willSaveDataToSharedPreference(){
when(sp.edit()).thenReturn(editor);
presenter.saveToSharedPref("my_key",10);
verify(editor,times(1)).putInt(any(String.class), any(Integer.class));
}
Upvotes: 0
Reputation: 575
I believe the issue is that because you are mocking the Editor
, when you call putString()
it will return a different object. Try mocking the putString()
method as well, like so:
when(mEditor.putString(anyString(), anyString())).thenReturn(mEditor);
Upvotes: 8