我有一个ObservableBoolean,它是一个包装基元布尔值的非常简单的数据容器。我想使用JUnit/Mockito来验证基元布尔值是否变为true,然后变为false。我正在设置一个模拟OnPropertyChangedCallback,如下所示:
Observable.OnPropertyChangedCallback loadingCallback = mock(Observable.OnPropertyChangedCallback.class);
viewModel.loading.addOnPropertyChangedCallback(loadingCallback);
然后我正在运行测试中的代码,它会:
loading.set(true);
loading.set(false);
这些调用中的每一个都在loadingCallback上激发onPropertyChanged方法,并将相同的ObservableBoolean实例作为参数传递。
我尝试过使用ArgumentCaptor和自定义ArgumentMatcher。这两个方法都成功地表明onPropertyChange方法已经被调用了两次,但是,它们都没有维护ObservableBoolean中原始布尔值的历史记录。相反,我只能看到上面设置的最新值,这是错误的。
如何维护ObservableBoolean中原始布尔值的历史记录?同样,我只需要验证它是否设置为true,然后是false。
您可以创建一个存根,它实现Observable.OnPropertyChangedCallback
并记录调用,然后为这些记录的调用提供公共访问器。然后,您的测试将在断言时对这些记录的调用使用公共访问器。
例如:
OnPropertyChangedCallbackStub loadingCallback = new OnPropertyChangedCallbackStub();
viewModel.loading.addOnPropertyChangedCallback(loadingCallback);
// invoke the code-under-test which, internally, invokes ...
// loading.set(true);
// loading.set(false);
assertTrue(2, loadingCallback.recordedInvocations().size());
assertTrue(loadingCallback.recordedInvocations().contains(true));
assertTrue(loadingCallback.recordedInvocations().contains(false));
我发布了@glytching在他的回答中建议的类的实现:
val callback = BooleanObservableCallback()
viewModel.isLoading.addOnPropertyChangedCallback(callback)
viewModel.onLoginButtonClicked()
assertThat(callback.recordedInvocations, hasSize(2))
assertThat(callback.recordedInvocations[0], `is`(true))
assertThat(callback.recordedInvocations[1], `is`(false))
class BooleanObservableCallback : Observable.OnPropertyChangedCallback() {
private val _recordedInvocations = mutableListOf<Boolean>()
val recordedInvocations: List<Boolean>
get() = _recordedInvocations.toList()
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
if (sender is ObservableBoolean) {
_recordedInvocations.add(sender.get())
}
}
}