如何通过 `Sample` 方法测试将值推送到使用 Reactive Extensions 的对象
How to test object that pushes values to using Reactive Extensions via `Sample` method
我有一个名为 ValuePusher
的 class 和一个名为 Value
的 属性 并接收类型为 ValueReceiver
的依赖项,也有一个 [=34] =] 命名为 Value
。前者 class 通过 System.Reactive.Subjects.Subject<int>
对象将 'push' 值安排到后者 class 的实例。最初它一对一地推送值,但稍后它将限制使用 Sample
方法推送的值的数量 - 请注意以下代码中对此方法的注释调用:
public sealed class ValuePusher : IDisposable
{
private readonly ValueReceiver _receiver;
private readonly IScheduler _scheduler;
private readonly Subject<int> _subject;
private int _value;
public ValuePusher(ValueReceiver receiver, IScheduler scheduler)
{
_receiver = receiver;
_scheduler = scheduler;
// Arrange to push values to `receiver` dependency
_subject = new Subject<int>();
_subject.ObserveOn(_scheduler)
//.Sample(TimeSpan.FromMilliseconds(50), _scheduler)
.SubscribeOn(_scheduler)
.Subscribe(i => PushCurrentValueToReceiver());
}
public int Value
{
get => _value;
set
{
_value = value;
_subject.OnNext(0);
}
}
private void PushCurrentValueToReceiver()
{
_receiver.Value = Value;
}
public void Dispose()
{
_subject?.OnCompleted();
_subject?.Dispose();
}
}
public class ValueReceiver
{
public int Value { get; set; }
}
我为上面的代码写了一个单元测试,涉及一个Microsoft.Reactive.Testing.TestScheduler
,通过了:
[TestMethod]
[Timeout(1000)]
public void ReceiverReceivesValueFromPusherViaScheduler()
{
var scheduler = new TestScheduler();
var receiver = new ValueReceiver();
using (var pusher = new ValuePusher(receiver, scheduler))
{
scheduler.Start();
pusher.Value = 1;
scheduler.AdvanceBy(1);
Assert.AreEqual(1, receiver.Value);
}
}
但是,如果取消注释对 Sample
方法的调用,测试将无法完成并超时。如何更改测试代码或生产代码以验证在使用 Sample
时是否将值推送到接收对象?
超时的原因,好像是.Sample(...)
和scheduler.Start()
的组合。
scheduler.Start()
尝试执行已安排的所有内容,但我认为 Sample()
一直在安排样本,因此 scheduler.Start()
永远不会完成。
因此,如果您删除 scheduler.Start()
,然后改为这样做:
...
// Following line instead of scheduler.Start(), needed because of the .SubscribeOn(...) call
scheduler.AdvanceBy(1);
pusher.Value = 1;
scheduler.AdvanceBy(TimeSpan.FromMilliseconds(50).Ticks);
Assert.AreEqual(1, receiver.Value);
...
无论是否调用 .Sample(...)
,它都应该工作。
[编辑] 根据 Dan Stevens 的评论。
我有一个名为 ValuePusher
的 class 和一个名为 Value
的 属性 并接收类型为 ValueReceiver
的依赖项,也有一个 [=34] =] 命名为 Value
。前者 class 通过 System.Reactive.Subjects.Subject<int>
对象将 'push' 值安排到后者 class 的实例。最初它一对一地推送值,但稍后它将限制使用 Sample
方法推送的值的数量 - 请注意以下代码中对此方法的注释调用:
public sealed class ValuePusher : IDisposable
{
private readonly ValueReceiver _receiver;
private readonly IScheduler _scheduler;
private readonly Subject<int> _subject;
private int _value;
public ValuePusher(ValueReceiver receiver, IScheduler scheduler)
{
_receiver = receiver;
_scheduler = scheduler;
// Arrange to push values to `receiver` dependency
_subject = new Subject<int>();
_subject.ObserveOn(_scheduler)
//.Sample(TimeSpan.FromMilliseconds(50), _scheduler)
.SubscribeOn(_scheduler)
.Subscribe(i => PushCurrentValueToReceiver());
}
public int Value
{
get => _value;
set
{
_value = value;
_subject.OnNext(0);
}
}
private void PushCurrentValueToReceiver()
{
_receiver.Value = Value;
}
public void Dispose()
{
_subject?.OnCompleted();
_subject?.Dispose();
}
}
public class ValueReceiver
{
public int Value { get; set; }
}
我为上面的代码写了一个单元测试,涉及一个Microsoft.Reactive.Testing.TestScheduler
,通过了:
[TestMethod]
[Timeout(1000)]
public void ReceiverReceivesValueFromPusherViaScheduler()
{
var scheduler = new TestScheduler();
var receiver = new ValueReceiver();
using (var pusher = new ValuePusher(receiver, scheduler))
{
scheduler.Start();
pusher.Value = 1;
scheduler.AdvanceBy(1);
Assert.AreEqual(1, receiver.Value);
}
}
但是,如果取消注释对 Sample
方法的调用,测试将无法完成并超时。如何更改测试代码或生产代码以验证在使用 Sample
时是否将值推送到接收对象?
超时的原因,好像是.Sample(...)
和scheduler.Start()
的组合。
scheduler.Start()
尝试执行已安排的所有内容,但我认为 Sample()
一直在安排样本,因此 scheduler.Start()
永远不会完成。
因此,如果您删除 scheduler.Start()
,然后改为这样做:
...
// Following line instead of scheduler.Start(), needed because of the .SubscribeOn(...) call
scheduler.AdvanceBy(1);
pusher.Value = 1;
scheduler.AdvanceBy(TimeSpan.FromMilliseconds(50).Ticks);
Assert.AreEqual(1, receiver.Value);
...
无论是否调用 .Sample(...)
,它都应该工作。
[编辑] 根据 Dan Stevens 的评论。