我在 MVVM 项目中使用 Rx 和 RxUI,并且有一个视图模型可以从 WCF 服务异步查询其数据。在单元测试中,我创建了一个模拟对象,它返回一个具有预期值的任务。
这是我的视图模型的大致概念
public class ViewModel : ReactiveObject
{
private IContext _context;
public ViewModel(IContext context)
{
_context = context;
Observable.FromAsync(() => _context.WcfServiceCall())
.Subscribe(result => {
Children.AddRange(results.Select(r => new ChildViewModel(r).ToList()));
});
}
public ObservableCollection<ChildViewModel> { get; private set;}
}
我的单元测试看起来像这样
[TestFixture]
public class ViewModelTest : AssertionHelper
{
[Test]
public void ShouldSetChildren()
{
var c = new Mock<IContext>();
c.Setup(q => q.WcfServiceCall())
.Returns(Task.Run(() => new []{ 1,2,3,4,5,6 })):
var vm = new ViewModel(c.Object);
var p = vm.Children.First(); // this call sometimes fails
...
}
}
我遇到的问题是,我有超过 400 个测试可以做这种事情,而且它们大部分时间都可以工作,但是我随机得到失败的测试,一次一两个,报告序列没有值。这是不可预测和随机的。我可以在失败后再次运行测试并且全部成功。我已按照此处所述添加了 TestScheduler,但问题仍然存在。
有没有更好的方法来测试进行异步方法调用的方法?
根据 Paul Bett 的输入进行编辑:我看到 FromAsync 不采用 IScheduler 参数,但我确实有可用的 SubscribeOn 和 ObserveOn。
或者,我可以直接调用 WCF 异步方法并将返回的 Task 转换为 observable。我不确定我是否理解何时使用 Observable.FromAsync 与不使用它更合适。