RX和异步Nunit测试

亚历克斯·奈特卡乔夫(Alex Netkachov)

我正在尝试为项目创建一个异步单元测试,但无法理解如何等待异步主题完成:

    [Test]
    public async void MicroTest()
    {
        var value = 2;

        var first = new AsyncSubject<int>();
        var second = new AsyncSubject<int>();

        first.Subscribe(_ =>
        {
            value = _;
            second.OnCompleted();
        });

        first.OnNext(1);

        // how to wait for the second subject to complete?

        Assert.AreEqual(value, 1);
    }

此测试的同步版本运行良好:

    [Test]
    public void MicroTest()
    {
        var value = 2;

        var first = new Subject<int>();
        var second = new Subject<int>();

        first.Subscribe(_ =>
        {
            value = _;
            second.OnCompleted();
        });

        first.OnNext(1);

        Assert.AreEqual(value, 1);
    }
詹姆斯世界

AsyncSubject与主题

首先,值得指出的AsyncSubject<T>不是的异步版本Subject<T>两者实际上都是自由线程*(请参阅脚注)。

AsyncSubject是专门Subject用于建模异步完成的操作并返回单个结果的操作。它具有两个值得注意的功能:

  • 仅发布最后结果
  • 结果将被缓存,完成后可供观察者使用。

它在内部广泛使用,包括通过ToObservable()定义扩展方法TaskTask<T>

测试的问题

调用AsyncSubject<T>只会返回收到的最终结果。它通过等待OnCompleted()来执行此操作,以便知道最终结果是什么。因为您不进行调用OnCompleted(),所以first测试是有缺陷的,因为OnNext()永远不会调用处理程序(在您的Subscribe调用中传递的lambda函数)。

此外,它是无效的不是调用OnNext()至少一次上的AsyncSubject<T>,所以当你打电话await second;,你会得到一个InvalidOperationException,如果你没有这样做。

如果按照以下方式编写测试,则一切正常:

[Test]
public async void MicroTest()
{
    var value = 2;

    var first = new AsyncSubject<int>();
    var second = new AsyncSubject<int>();

    first.Subscribe(_ =>
    {
        // won't be called until an OnCompleted() has
        // been invoked on first
        value = _;
        // you must send *some* value to second
        second.OnNext(_);
        second.OnCompleted();
    });

    first.OnNext(1);
    // you must do this for OnNext handler to be called
    first.OnCompleted(); 

    // how to wait for the second subject to complete
    await second;

    Assert.AreEqual(value, 1);
}

关于异步测试

通常,我会避免编写可能永远等待的异步测试。当它导致构建服务器上的资源耗尽时,这尤其令人讨厌。使用某种超时,例如:

await second.Timeout(TimeSpan.FromSeconds(1));

无需处理异常,因为这足以使测试失败。

**我已从COM词典中借用了这个词从这个意义上讲,我的意思是,与大多数Rx框架组件一样,它们通常将在您碰巧调用其方法的任何线程上运行。但是,使用自由线程并不一定意味着完全线程安全。特别是,与有所不同的是AsyncSubject<T>Subject<T>它不会保护您免受Rx语法对重复调用的侵犯OnNext使用Subject.SynchronizeObservable.Synchronize进行此保护。*

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

异步测试在Nunit 2.6.2中挂起

来自分类Dev

NUnit和测试Xamarin PCL

来自分类Dev

NUnit异步测试+ RequiresSTA =>等待不返回STA线程

来自分类Dev

使用NUnit使用异步/等待方法进行单元测试

来自分类Dev

异步 NUnit 测试方法通过后等待调用

来自分类Dev

使用NUnit和Moq测试等待的呼叫

来自分类Dev

使用Selenium和Nunit的并行测试失败

来自分类Dev

C# NUnit 和测试元组

来自分类Dev

如何使用 NUnit 通过异步单元测试来测试竞争条件?

来自分类Dev

单元测试和多个异步任务

来自分类Dev

测试和模拟使用异步语句的异步代码

来自分类Dev

Moq:如何使用Nunit和内部HttpClient测试类?

来自分类Dev

ReSharper和NUnit的单元测试得出不同的结果

来自分类Dev

Visual Studio和NUnit->缺少测试菜单项

来自分类Dev

nunit-console无法使用TestCase和TestCaseSource运行测试

来自分类Dev

使用nunit-console和mono运行硒测试

来自分类Dev

未使用 NUnit、Selenium 和 C# 运行的测试执行

来自分类Dev

如何在NUnit中测试此视图模型的异步行为?

来自分类Dev

如何在NUnit中测试此视图模型的异步行为?

来自分类Dev

Rx-fied vertx.io 和 junit 测试

来自分类Dev

使用 TestScheduler、Rx 和 BlockingCollection 进行死锁测试

来自分类Dev

RX异步未执行

来自分类Dev

更改NUnit测试的名称

来自分类Dev

使用Nunit测试异常

来自分类Dev

如何运行NUnit测试?

来自分类Dev

Nunit测试案例问题

来自分类Dev

Nunit“分区”测试

来自分类Dev

C# NUnit 测试

来自分类Dev

使用Karma和Mocha进行异步测试