如何单独测试Rx.Net foreach订阅

时间:2017-11-11 14:35:00

标签: c# unit-testing system.reactive rx.net

所有消息都应发布到消息总线:

 upstream.Get().ForEachAsync(async e => await _bus.Publish(e, cancellationToken));

我想进行单元测试以验证是否正确调用了发布方法:

    [Theory, AutoMoqData]
    public void Publish_ShouldPublishAllDataSources(
        [Frozen]Mock<IBus> bus,
        [Frozen]Mock<IUpstream> upstream,
        SUT sut,
        TestScheduler scheduler,
        CancellationToken cancellationToken
        )
    {
        {
            Arrange();
            Act();
            Assert();
        }
        ITestableObservable<Event> inputObservable;

        void Arrange()
        {
            inputObservable =
                    scheduler.CreateColdObservable(
                        OnNext(1L,new Event("e1")),
                        OnNext(1L,new Event("e2")),
                        OnNext(1L,new Event("e3"))
                    );
            upstream
            .Setup(c => c.Get())
            .Returns(inputObservable);


        }

        void Act()
        {
            sut.Exercise(cancellationToken);
            //Do sth with scheduller to fire all events 
            //I've tested these:
            //scheduler.Start();
            //scheduler.AdvanceTo(30000L);
        }


        void Assert()
        {
            inputObservable.ForEach(e =>
                bus.Verify(b => 
                    b.Publish(e, cancellationToken)
                ));
        }
    }

但无论我尝试什么测试都不会停止。

更新:

这是完整的生产代码:

class SUT 
{
     IUpstream _upstream;
     public SUT(IUpstream upstream)
     {
          _upstream = upstream;
     }
     void Exercise(CancellationToken cancellationToken)
     {
         _upstream .Get()
               .ForEachAsync(async 
                    e => await _bus.Publish(e, cancellationToken));
     }
}


interface IUpstream
{
    IObservable<string> Get();
}

interface IBus
{
    void Publish<T>(T,System.Threading.CancellationToken)
}

1 个答案:

答案 0 :(得分:1)

ITestableObservable<T>.Messages应该用于断言而不是ITestableObservable<T>本身。

    void Assert()
    {
        inputObservable
                .Messages.ToList()
                .ForEach(e =>
                bus.Verify(b =>
                    b.Publish(e.Value.Value, cancellationToken)));
    }

所以行动应该如下:

    void Act()
    {
        sut.Exercise(cancellationToken);
        scheduler.Start();
        //OR:
        //scheduler.AdvanceBy(1L);
    }