C# 如何将ServiceStack.GetAsync与ReactiveCommand(v6)一起使用
我正在尝试将C# 如何将ServiceStack.GetAsync与ReactiveCommand(v6)一起使用,c#,
servicestack,async-await,reactiveui,C#,
servicestack,Async Await,Reactiveui,我正在尝试将ReactiveCommand与组合 从未调用x=>\u reactiveList.AddRange(x),测试res为空。我现在不知道如何将ServiceStack的任务GetAsync(IReturn requestDto)结果转换为反应式IObservable 解决了问题,但这不是一个选项。您在反应UI端做的一切都是正确的,ServiceStack出现了一些问题 好吧,有几件事可能是错的。一切看起来都应该运行,但你永远不知道 我确实知道,当直接处理任务和TestSchedule
ReactiveCommand
与组合
从未调用x=>\u reactiveList.AddRange(x)
,测试res
为空。我现在不知道如何将ServiceStack的任务GetAsync(IReturn requestDto)
结果转换为反应式IObservable
解决了问题,但这不是一个选项。您在反应UI端做的一切都是正确的,ServiceStack出现了一些问题 好吧,有几件事可能是错的。一切看起来都应该运行,但你永远不知道 我确实知道,当直接处理任务和
TestScheduler
时,在ReactiveUI中通常会有一些奇怪的东西,所以在这方面有一些东西可以尝试
任务
转换为IObservable
ServiceCommandTask()
方法返回一个IObservable
,而不使用async/await
。要做到这一点,您必须更改创建ReactiveCommand
的方式,以使用ReactiveCommand.CreateAsyncObservable
,您只需在从ServiceStack调用返回的任务中使用ServiceCommandTask()
将
任务
转换为IObservable
可能有效的原因是TestScheduler
依赖虚拟时间等待事情发生。TestSchedluer
无法与Task
正确交互,因此当它向前“跳过”1秒时,在现实世界中实际上没有时间。如果ServiceStack调用没有立即返回,那么我认为情况会是这样,通过上述解决方案,该问题可能可以解决,也可能无法解决。我认为这是时间问题,但我不知道如何解决它。上的示例代码GitHub@Tomasito是的,我想你最大的问题是你是。这是一个集成测试,因为它使用ServiceStack依赖项而不是模拟它。因为您试图执行的操作需要实时执行,AdvanceByMs(1000)
根本帮不上您的忙。相反,您必须等待实时,这意味着您必须使用Thread.Sleep(1000)
Thread.Sleep(1000)
仅在Main(string[]args)
中工作,当在TestMethod1
中时,它会给我ServiceStack.webserviceeexception:methodnotallowed
异常。最后执行的方法是System.Reactive.ScheduledObserver
1.Run(对象状态,动作1递归)
。我所有的架构都错了吗?我的意思是从ReactiveCommand调用服务?@Tomasito我想说,当您进行单元测试时,从ReactiveCommand调用ServiceStack是不好的,因为此时您正试图同时测试ServiceStack和ReactiveCommand。我会将您的GetAsync
方法移动到一个可以在单元测试中模拟(即用虚拟版本替换)的接口中,以便您测试的唯一功能是您的ReactiveCommand功能。如果您需要测试ServiceStack是否工作,那么您应该为此进行不同的单元测试。我需要至少一个测试来确保它们一起工作。是吗?
public ReactiveCommand<IList<string>> ServiceReadCommand { get; protected set; }
public ReactiveList<string> ReactiveList
{
get { return _reactiveList; }
set { _reactiveList = this.RaiseAndSetIfChanged(ref _reactiveList, value); }
}
private ReactiveList<string> _reactiveList = new ReactiveList<string>();
public TestViewModel(IScreen screen = null)
{
HostScreen = screen;
ServiceReadCommand = ReactiveCommand.CreateAsyncTask(x => ServiceCommandTask(), RxApp.TaskpoolScheduler);
ServiceReadCommand.ThrownExceptions.Subscribe(x => Console.WriteLine((object)x));
ServiceReadCommand.Subscribe(x => _reactiveList.AddRange(x));
}
private async Task<IList<string>> ServiceCommandTask()
{
this.Log().Info("Service command task");
var baseUri = "http://localhost:9010";
var client = new JsonServiceClient(baseUri);
// Works
return await Observable.Return(new List<string> { "" });
// Don't
return await client.GetAsync(new TestRequest());
}
[TestMethod]
public void TestMethod1()
{
IList<string> res = null;
new TestScheduler().With(sched =>
{
var viewModel = new TestViewModel();
viewModel.ServiceReadCommand.CanExecute(null).Should().BeTrue();
viewModel.ServiceReadCommand.ExecuteAsync(null).Subscribe(x => res = x);
sched.AdvanceByMs(1000);
return viewModel.ReactiveList;
});
res.Should().NotBeEmpty();
}
viewModel.ServiceReadCommand.ExecuteAsync(null).Subscribe(x => res = x);
//Thread.Sleep(1000);
sched.AdvanceByMs(1000);
using System.Reactive.Linq;
// ...
return await (client.GetAsync(new TestRequest()).ToObservable());