使用Mockito模拟Android单元测试中的共享首选项时出错

使用Mockito模拟Android单元测试中的共享首选项时出错,android,sharedpreferences,mockito,Android,Sharedpreferences,Mockito,我试图通过使用Mockito库模拟Android共享偏好来编写单元测试,但即使多次尝试,它也不适用于我。请检查我下面的示例代码,让我知道它出了什么问题 我目前正在使用“JCAndKSolutions/android单元测试”android junit插件 我的代码如下: PreferenceHelper.java PreferenceHelperTest.java public class PreferencesHelperTest extends TestCase { @Mock

我试图通过使用Mockito库模拟Android共享偏好来编写单元测试,但即使多次尝试,它也不适用于我。请检查我下面的示例代码,让我知道它出了什么问题

我目前正在使用“JCAndKSolutions/android单元测试”android junit插件

我的代码如下:

PreferenceHelper.java

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();
    }
}
如果我运行这个junit测试,我会得到以下错误

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)
在调试时,我发现调用putString()方法时会引发nullPointer异常


是否有任何帮助或线索表明错误出在哪里???

我认为问题在于,因为您正在模拟
编辑器,当您调用
putString()
时,它将返回一个不同的对象。尝试模拟
putString()
方法,如下所示:

当(mEditor.putString(anyString(),anyString())。然后返回(mEditor);

这对我有用

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));
}

感谢@Matt为您提供反馈,我将面对同样的问题。你能帮帮我吗?你是如何修复这个共享引用和编辑器模拟的?
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));
}