イベントストリームの非アクティブをテストするRXコードがありますが、ストリームのアクティビティは非アクティブトリガの間隔をリセットします。RX:サンプルの Interval Switchパイプラインをテストします
本当の問題 - (ObserveInactivityは、ちょうど最後のアクティビティのタイムスタンプに基づいてタイムアウトとリセット前のサンプルなければならない、私は間隔が毎秒再作成することはキル上だと思いますが)必要に応じて
public interface IReportActivity
{
event EventHandler Activity;
}
public interface IInactivityMonitor
{
IObservable<Unit> ObserveInactivity(TimeSpan inactivityTimeout);
}
public class InactivityMonitor : IInactivityMonitor
{
private readonly ISchedulerProvider _schedulerProvider;
private readonly IReportActivity _activitySource;
private IObservable<Unit> _inactivityObservable;
public InactivityMonitor(IRaiseActivity activitySource, ISchedulerProvider schedulerProvider)
{
_activitySource = activitySource;
_schedulerProvider = schedulerProvider;
}
public IObservable<Unit> ObserveInactivity(TimeSpan inactivityTimeout)
{
return GetInactivityObservable()
.Select(_ => Observable.Interval(inactivityTimeout, _schedulerProvider.NewThread)
.Timestamp()
.Select(__ => Unit.Default))
.Switch();
}
public IObservable<Unit> GetInactivityObservable()
{
return _inactivityObservable = _inactivityObservable ??
Observable.FromEventPattern<EventHandler<EventArgs>, EventArgs>(
h => _activitySource.Activity += h,
h => _activitySource.Activity -= h)
.Sample(TimeSpan.FromSeconds(1), _schedulerProvider.NewThread)
.Select(_ => Unit.Default)
.Publish()
.RefCount();
}
}
コードは動作します私はこのコードをテストしようとしています。
[TestFixture]
public class InactivityMonitorTests
{
private TestSchedulers _testSchedulers;
private InactivityMonitor _sut;
private AutoMock _moqqer;
protected override void Setup()
{
base.Setup();
_moqqer = new AutoMock()
_testSchedulers = new TestSchedulers();
_moqqer.Use<ISchedulerProvider>(_testSchedulers);
_sut = Moqqer.CreateInstance<InactivityMonitor>();
}
// this test passes
[Test]
public void GetInactivityObservable_ActivityDetected_ReportsActivity()
{
var activityObserved = false;
_sut.GetInactivityObservable()
.Subscribe(x => activityObserved = true);
RaiseActivityEvent();
_testSchedulers.NewThread.AdvanceBy(TimeSpan.FromSeconds(11).Ticks);
activityObserved.Should().BeTrue();
}
private void RaiseActivityEvent()
{
_moqqer.GetMock<IReportActivty>()
.Raise(m => m.Activity += null, EventArgs.Empty);
}
// this test fails, The interval never appears to get set up via the tests.
[Test]
public void ObserveActivity_InactivtyTimeoutExceeded_NotificationReceived()
{
var inactivityObserved = false;
_sut.ObserveInactivity(TimeSpan.FromSeconds(10))
.Subscribe(x => inactivityObserved = true);
_testSchedulers.NewThread.AdvanceBy(TimeSpan.FromSeconds(11).Ticks);
inactivityObserved.Should().BeTrue();
}
}
public interface ISchedulerProvider
{
IScheduler CurrentThread { get; }
IScheduler Dispatcher { get; }
IScheduler Immediate { get; }
IScheduler NewThread { get; }
IScheduler ThreadPool { get; }
IScheduler TaskPool { get; }
}
public sealed class TestSchedulers : ISchedulerProvider
{
private readonly TestScheduler _currentThread = new TestScheduler();
private readonly TestScheduler _dispatcher = new TestScheduler();
private readonly TestScheduler _immediate = new TestScheduler();
private readonly TestScheduler _newThread = new TestScheduler();
private readonly TestScheduler _threadPool = new TestScheduler();
private readonly TestScheduler _taskPool = new TestScheduler();
#region Explicit implementation of ISchedulerService
IScheduler ISchedulerProvider.CurrentThread { get { return _currentThread; } }
IScheduler ISchedulerProvider.Dispatcher { get { return _dispatcher; } }
IScheduler ISchedulerProvider.Immediate { get { return _immediate; } }
IScheduler ISchedulerProvider.NewThread { get { return _newThread; } }
IScheduler ISchedulerProvider.ThreadPool { get { return _threadPool; } }
IScheduler ISchedulerProvider.TaskPool { get { return _taskPool; } }
#endregion
public TestScheduler CurrentThread { get { return _currentThread; } }
public TestScheduler Dispatcher { get { return _dispatcher; } }
public TestScheduler Immediate { get { return _immediate; } }
public TestScheduler NewThread { get { return _newThread; } }
public TestScheduler ThreadPool { get { return _threadPool; } }
public TestScheduler TaskPool { get { return _taskPool; } }
}
私が加入していないとした後、別のスケジューラ上で購読しようとする前に、サブスクライブすることを開始するが、何の成功の前に、スケジューラを起動するためのさまざまな方法を試してみました。
EDIT:デバッグでは、ObserveInactivityメソッドで間隔が決して生成されないことが示されます。
誰かが私を正しい方向に向けることができます。
おかげ
私はあなた 'ISchedulerProvider'と' TestSchedulers'がhttp://introtorx.comからである推測するつもりですか? – Shlomo
はい、元の投稿に言及するのを忘れてしまった。 – antinutrino
はスケジューラのコードを投稿しました – antinutrino