我在仪器测试中遇到一个问题,该测试正在检查活动,其中一种方法将其状态保存到共享偏好。测试的代码看起来像:
initialPresenter.getLocalData().edit()
.putString("SessionDetails", new Gson().toJson(sessionData))
.putBoolean("relog", false)
.apply();
LocalData由Dagger2注入了演示者。我已经为此创建了模拟,并且正在补充它们,所以那里的一切都很好。例如
when(localData.getBoolean("signed_using_email", false)).thenReturn(true);
我试图以某种方式禁用或使用编辑数据时会出现问题。我创建了另一个模拟;编辑器的这段时间,因此当共享pref调用编辑时,它得到了明确的模拟;
@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
哪个顺便说一句。怪异的是怪异吗?看来第一个模拟工作正好很好,但是后来嵌套了(?)并引发错误。
还尝试了另一种方法,而不是我使用的donothing;
而不是固执/替换答案;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.Editor
具有'构建器'语法,每个调用putString()
,putBoolean()
等。返回Editor
。
当您模拟此对象时,您希望每次调用这些方法之一。
根据杰夫·鲍曼(Jeff Bowman)在使用Mockito嘲笑建造者语法上的答案,您可以使用代码的以下更改来执行此操作:
@Mock(answer = RETURNS_SELF) SharedPreferences.Editor mEditor;
另外,您可能只想使用returns_deep_stubs:
mEditor = mock(SharedPreferences.Editor.class, RETURNS_DEEP_STUBS);