使用 Mockito 在 Android 单元测试中模拟共享首选项时出错
Error in Mocking Shared Preference in Android Unit Test using Mockito
我正在尝试使用 Mockito 库通过模拟 Android 共享首选项来编写单元测试,但即使经过多次尝试,它对我也不起作用。请检查下面我的示例代码,让我知道它出了什么问题
我目前正在使用"JCAndKSolutions/android-unit-test" android junit插件。
我的代码如下:
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();
}
}
如果我运行这个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 异常。
哪里出错了有什么帮助或线索吗??
我认为问题在于,因为您正在模拟 Editor
,当您调用 putString()
时,它会 return 一个不同的对象。也尝试模拟 putString()
方法,如下所示:
when(mEditor.putString(anyString(), anyString())).thenReturn(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));
}
我正在尝试使用 Mockito 库通过模拟 Android 共享首选项来编写单元测试,但即使经过多次尝试,它对我也不起作用。请检查下面我的示例代码,让我知道它出了什么问题
我目前正在使用"JCAndKSolutions/android-unit-test" android junit插件。
我的代码如下:
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();
}
}
如果我运行这个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 异常。
哪里出错了有什么帮助或线索吗??
我认为问题在于,因为您正在模拟 Editor
,当您调用 putString()
时,它会 return 一个不同的对象。也尝试模拟 putString()
方法,如下所示:
when(mEditor.putString(anyString(), anyString())).thenReturn(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));
}