考虑以下方法:
如果我将黑客放置到位,我的单元测试会立即完成,并且“可观察到没有数据”。
如果我拿出黑客,有多个线程都试图同时登录 主机服务不允许。
如何确保在任何给定时间点只有一个 生成 observables。
private static object obj = new object();
private static bool here = true;
public IObservable<Party> LoadAllParties(CancellationToken token)
{
var parties = Observable.Create<Party>(
async (observer, cancel) =>
{
// this is just a hack to test behavior
lock (obj)
{
if (!here)
return;
here = false;
}
// end of hack.
try
{
if (!await this.RequestLogin(observer, cancel))
return;
// request list.
await this._request.GetAsync(this._configuration.Url.RequestList);
if (this.IsCancelled(observer, cancel))
return;
while (!cancel.IsCancellationRequested)
{
var entities = await this._request.GetAsync(this._configuration.Url.ProcessList);
if (this.IsCancelled(observer, cancel))
return;
var tranche = this.ExtractParties(entities);
// break out if it's the last page.
if (!tranche.Any())
break;
Array.ForEach(tranche, observer.OnNext);
await this._request.GetAsync(this._configuration.Url.ProceedList);
if (this.IsCancelled(observer, cancel))
return;
}
observer.OnCompleted();
}
catch (Exception ex)
{
observer.OnError(ex);
}
});
return parties;
}
我的单元测试:
var sut = container.Resolve<SyncDataManager>();
var count = 0;
var token = new CancellationTokenSource();
var observable = sut.LoadAllParties(token.Token);
observable.Subscribe(party => count++);
await observable.ToTask(token.Token);
count.Should().BeGreaterThan(0);
答案 0 :(得分:3)
我确实认为你的问题正在受到XY Problem的影响 - 代码中包含多次调用未包含的方法,这些方法可能包含重要的副作用,我觉得继续提供的信息不会导致最好的建议。
也就是说,我怀疑您不打算两次订阅observable
- 一次使用明确的Subscribe
来电,一次使用ToTask()
来电。这肯定会解释并发调用,它们发生在两个不同的订阅中。
编辑:
如何在长度上断言(调整超时以适应):
var length = await observable.Count().Timeout(TimeSpan.FromSeconds(3));
最好是调查Rx-Testing并模拟您的依赖项。这是一个很大的话题,但this long blog post from the Rx team explains it very well这个关于TPL-Rx相互作用的答案可能有所帮助:Executing TPL code in a reactive pipeline and controlling execution via test scheduler