Ashwin
Ashwin

Reputation: 118

Error in Mocking Shared Preference in Android Unit Test using Mockito

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

Answers (2)

Md. Tahmid Mozaffar
Md. Tahmid Mozaffar

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

Matt Kranzler
Matt Kranzler

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

Related Questions