NUnit在单独的线程中断言

时间:2011-06-21 10:50:21

标签: 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();
                       });
}

2 个答案:

答案 0 :(得分:7)

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

legacyUnhandledExceptionPolicy

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

虽然在我看来比忽略更好。

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

ReSharper test runner – hidden thread exceptions

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

受控示例

    [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.");
    }

答案 1 :(得分:1)

Assert.IsTrue(false);

将在DoesNotThrow调用之前抛出异常。但是NUnit不适用于多个线程。跨线程比UnitTest更集成。一般来说,我建议避免从外部公开线程/任务并使用过的对象的内部行为 - 以便您可以模拟此行为以进行测试。