我正在尝试为在我的模型(Foo)上调用异步方法的 Viewmodel 编写集成测试。 但是我无法让定时/线程/异步处理工作。
我已经将问题简化为下面的代码。目前此测试失败,因为 myFoo.Value 的实际值为 0 而不是 123。
using System.Reactive;
using Microsoft.Reactive.Testing;
using ReactiveUI.Testing;
using ReactiveUI.Fody.Helpers;
using ReactiveUI;
using System.Reactive.Linq;
using System.Reactive.Concurrency;
namespace Cooler.Test;
public class Foo
{
public int Value { get; private set; }
public Foo() => Value = 42;
public async Task<Unit> SetValueAsync(int value)
{
await RxApp.TaskpoolScheduler.Sleep(TimeSpan.FromMilliseconds(10));
Value = value;
return Unit.Default;
}
}
public class ViewModel : ReactiveObject
{
public ViewModel(Foo foo)
{
this.WhenAnyValue(x => x.Setpoint)
//.Skip(1) // Skip the initial value
.ObserveOn(RxApp.MainThreadScheduler)
.SelectMany(foo.SetValueAsync)
.Subscribe();
}
[Reactive]
public int Setpoint { get; set; }
}
public class Test
{
[Fact]
public void ShouldCallAsyncMethodOnSettingReactiveSetpoint()
{
new TestScheduler().With(scheduler =>
{
//set
var myFoo = new Foo();
var myVm = new ViewModel(myFoo);
//act
scheduler.AdvanceBy(1); //process the initial value if not skipped
scheduler.AdvanceByMs(20); //async processing
myVm.Setpoint = 123;
scheduler.AdvanceBy(2); //process reactive
scheduler.AdvanceByMs(20); //I expect it to process setpoint setting
//assert
Assert.Equal(123, myFoo.Value);
});
}
}
我预计该值为 123。但是 foo.SetValueAsync 未使用 123 进行调用。仅使用值 0 进行初始调用。如果我使用 Skip(1) 行,则该值为 42,从之前的结果来看,这是合乎逻辑的。
为什么这个测试失败?
我错误地认为 SelectMany 调用的方法也可以在 RxApp.MainThreadScheduler 上运行。事实并非如此。因此,在调用 SetValueAsync 之前,Assert 已完成。