我想测试我的Android视图模型,特别是当setter是否应该通知更改时。
视图模型如下所示(具有更多可绑定属性):
public class EditViewModel extends BaseObservable {
private String _comment;
@Bindable
public String getComment() {
return _comment;
}
public void setComment(String comment) {
if (_comment == null && comment == null) {
// No changes, both NULL
return;
}
if (_comment != null && comment != null && _comment.equals(comment)) {
//No changes, both equals
return;
}
_comment = comment;
// Notification of change
notifyPropertyChanged(BR.comment);
}
}
在我的单元测试中,我注册了一个监听器来接收通知,并使用以下类对其进行跟踪:
public class TestCounter {
private int _counter = 0;
private int _fieldId = -1;
public void increment(){
_counter++;
}
public int getCounter(){
return _counter;
}
public void setFieldId(int fieldId){
_fieldId = fieldId;
}
public int getFieldId(){
return _fieldId;
}
}
所以我的测试方法看起来像下面这样:
@Test
public void setComment_RaisePropertyChange() {
// Arrange
EditViewModel sut = new EditViewModel(null);
sut.setComment("One");
final TestCounter pauseCounter = new TestCounter();
// -- Change listener
sut.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
pauseCounter.increment();
pauseCounter.setFieldId(propertyId);
}
});
String newComment = "two";
// Act
sut.setComment(newComment);
// Assert
assertThat(pauseCounter.getCounter(), is(1));
assertThat(pauseCounter.getFieldId(), is(BR.comment));
assertThat(sut.getComment(), is(newComment));
}
如果我只执行测试方法,这种方法效果很好。如果我一次性执行所有测试,有些测试会失败,因为通知被调用的次数是0。我认为,在回调处理之前,断言已经被调用了。
我已经尝试过以下方法:
(1) 用Mockito模拟监听器,如https://fernandocejas.com/2014/04/08/unit-testing-asynchronous-methods-with-mockito/中所述。
@Test
public void setComment_RaisePropertyChange() {
// Arrange
EditViewModel sut = new EditViewModel(null);
sut.setComment("One");
Observable.OnPropertyChangedCallback listener = mock(Observable.OnPropertyChangedCallback.class);
// -- Change listener
sut.addOnPropertyChangedCallback(listener);
String newComment = "two";
// Act
sut.setComment(newComment);
// Assert
verify(listener, timeout(500).times(1)).onPropertyChanged(any(Observable.class), anyInt());
}
(2) 尝试使用多个SO答案中描述的CountDownLatch
。
但是它们都没有帮助我。我该怎么做才能测试绑定通知呢?