NUnit在单独的线程中断言

Ed.*_*ard 4 multithreading nunit

nunit是否适用于多线程上下文.我当然不希望nunit测试我的多线程应用程序,但是想要使用nunit断言

简单的例子 - 这个测试是"绿色".我错了什么?

[Test]
public void Test()
{
  Action action = Async;
  action.BeginInvoke(action.EndInvoke, null).AsyncWaitHandle.WaitOne();
}

private void Async()
{
  Assert.IsTrue(false);
  Assert.DoesNotThrow( () =>
                       {
                         Console.WriteLine("Async");
                         throw new InvalidOperationException();
                       });
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*oyd 7

NUnit测试运行程序可执行文件配置为忽略非测试线程上的异常.您可以通过app.config配置元素配置此行为:

legacyUnhandledExceptionPolicy

您可以将非测试线程配置为导致未处理的异常,因此测试将失败.需要注意的是,在另一个测试运行时可能会引发非测试线程异常,因此您可能无法准确了解哪个测试失败.此外,由于这将是一个未处理的异常,测试执行将在异常发生时停止,而不是继续,这是正常行为.

在我看来,比忽略更好.

以下文章详细介绍了ReSharper测试运行器的主题,但原理是相同的.

ReSharper测试运行器 - 隐藏线程异常

如果你确实有多线程方面,从断言的角度来看,我发现在非测试线程上设置标志等更好,等待非测试线程完成,然后在测试线程上断言状态.这样就可以在主线程上引发断言异常,并按预期运行测试.

受挫的例子

    [Test]
    public void Test()
    {
        Exception ex = null;

        Action test = () =>
        {
            Console.WriteLine("Async");

            ex = new InvalidOperationException();
        };

        test.BeginInvoke(test.EndInvoke, null).AsyncWaitHandle.WaitOne();

        Assert.That(ex, Is.Null, "Exception did not happen.");
    }
Run Code Online (Sandbox Code Playgroud)