我有一个工具测试问题,它检查在其中一种方法中将其状态保存为共享首选项的活动。经测试的代码如下所示:使用Mockito和Dagger的SharedPreferences
initialPresenter.getLocalData().edit()
.putString("SessionDetails", new Gson().toJson(sessionData))
.putBoolean("relog", false)
.apply();
LocalData通过dagger2注入演示者。我已经为它创建了模拟,并且我正在补充它们,所以在那里一切正常。例如。
when(localData.getBoolean("signed_using_email", false)).thenReturn(true);
当我试图以某种方式禁用或忽略编辑数据时会出现问题。我创造了另一个模拟;这次的编辑器,所以当SharedPref调用编辑它显式模拟;
@Mock SharedPreferences.Editor mEditor;
.
.
.
when(localData.edit()).thenReturn(mEditor);
但后来我得到错误:
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.content.SharedPreferences$Editor android.content.SharedPreferences$Editor.putBoolean(java.lang.String, boolean)' on a null object reference
其中顺便说一句。怪吓人怪异,为什么putBoolean没有putString?它看起来像第一个模拟工程很好,但它然后嵌套(?)并抛出错误。
也尝试了另一种方法,而不是桩/替换答案我用过没有;
doNothing().when(localData).edit();
但它也造成了类似的问题抛出错误:
org.mockito.exceptions.base.MockitoException:
Only void methods can doNothing()!
Example of correct use of doNothing():
doNothing().
doThrow(new RuntimeException())
.when(mock).someVoidMethod();
Above means:
someVoidMethod() does nothing the 1st time but throws an exception the 2nd time is called
任何想法如何解决呢?我不需要保存任何状态,以后我可以嘲笑它,这很好,因为我会通过编写这些测试来获得文档。早些时候,我使用PowerMockito来压缩使用sharedPreferences的整个方法,但是这个解决方案似乎并不好。
你的问题本质上是如何模拟'SharedPreferences.Editor'的'builder'语法。查看[Jeff Bowman的回答](https://stackoverflow.com/questions/8501920/how-to-mock-a-builder-with-mockito)了解如何使用Mockito完成此操作。换句话说,尝试'@Mock(answer = RETURNS_SELF)SharedPreferences.Editor mEditor;' –
@DavidRawson谢谢!我已经改变了创建模拟为 mEditor = mock(SharedPreferences.Editor.class,RETURNS_DEEP_STUBS); 它似乎工作。你能发表你的评论作为答案,所以我可以接受它吗? :) – Kamajabu