Nunit: Assert.Throwsは非同期デリゲートでは機能しません

作成日 2016年01月12日  ·  9コメント  ·  ソース: nunit/nunit

このテストケースの場合:

using System;
using System.Threading.Tasks;
using NUnit.Framework;

namespace NUnitAsync
{
    [TestFixture]
    public class Class1
    {
        [Test]
        public void MyAsyncThingTest()
        {
            var ioe = Assert.Throws<InvalidOperationException>(async () => await DelayedFailureAsync());
            Assert.That(ioe.Message, Is.EqualTo("ABC"));
        }

        [Test]
        public void MyAsyncThingFluentTest()
        {
            Assert.That(async () => await DelayedFailureAsync(), Throws.Exception.TypeOf<InvalidOperationException>().And.Message.EqualTo("ABC"));
        }

        static async Task DelayedFailureAsync()
        {
            await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
            throw new InvalidOperationException("ABC");
        }
    }
}

:negative_squared_cross_mark: MyAsyncThingTestはこの例外で失敗します:

Test Name:  MyAsyncThingTest
Test FullName:  NUnitAsync.Class1.MyAsyncThingTest
Test Source:    C:\Temp\NUnitAsync\NUnitAsync\Class1.cs : line 15
Test Outcome:   Failed
Test Duration:  0:00:00.004

Result StackTrace:  
at NUnit.Framework.Internal.AsyncInvocationRegion.Create(MethodInfo method)
   at NUnit.Framework.Assert.Throws(IResolveConstraint expression, TestDelegate code, String message, Object[] args)
   at NUnit.Framework.Assert.Throws[TActual](TestDelegate code, String message, Object[] args)
   at NUnit.Framework.Assert.Throws[TActual](TestDelegate code)
   at NUnitAsync.Class1.MyAsyncThingTest() in C:\Temp\NUnitAsync\NUnitAsync\Class1.cs:line 16
Result Message: System.ArgumentException : 'async void' methods are not supported, please use 'async Task' instead

:white_check_mark: MyAsyncThingFluentTestパス。

なぜ違いがあるのですか? Assert.Throwsは、さらにテストするための例外を返します。これは、 Assert.Thatスタイルでは提供されない便利な機能です。

duplicate

最も参考になるコメント

Stackoverflowが私をここに連れてきました。 すごい仕事!! NuGetで3.20バージョンに更新し、Assert.ThrowsAsyc関数を使用できました。

全てのコメント9件

レポートをありがとう。 これを確認し、優先度の高い問題として割り当てました。 どちらのインスタンスもTestDelegateを使用するため、同じように動作する必要があります。

Assert.Thatが例外を返さない理由は、署名に基づいてどの制約を使用するかがわからないためです。 呼び出しているのと同じメソッドであるAssert.That(async () => await One(), Is.EqualTo(1)));ような流暢なアサートを書くのが一般的です。

興味深いことに、これはスロー制約の問題にすぎないようです。 他の制約は機能します、

`` `C#
[テスト]
public void TestTheMeaningOfLife()
{{
Assert.That(async()=> DelayedMeaningOfLife()、Is.EqualTo(42));を待ちます。
}

静的非同期タスクDelayedMeaningOfLife()
{{
Task.Delay(TimeSpan.FromSeconds(2))。ConfigureAwait(false);を待ちます。
42を返します。
}
`` `

スロー制約の問題とはどういう意味ですか? Assert.Throwsが内部でそれを使用しない限り、throws制約( Assert.That(..., Throws...) )は機能します。 動作していないのはAssert.Throwsです。

Assert.ThatThrowsで機能する場合、 Is.EqualToや友人でも機能すると思います。

私の間違いは、どのテストが失敗したかを読み間違え、さらにどのテストが失敗したかを読み間違えたことです。 したがって、制約に関する私のコメントは正しくありません。 Assert.Throwsは、同等の制約に連鎖しない数少ない古典的なアサーションの1つです。

#1142で修正されましたが、文書化する必要があります。

ありがとう。

#1142への変更からはわかりませんが、エラーメッセージ(「非同期voidメソッドはサポートされていません」)が残っていますか、それとも開発者が代わりにAssert.ThrowsAsyncを使用する必要があることを示していますか?

@ yaakov-h、はい、次のバージョンをリリースしたら、代わりにAssert.ThrowsAsyncを使用する必要があります。 今のところ、流暢な構文を使用してください。

Stackoverflowが私をここに連れてきました。 すごい仕事!! NuGetで3.20バージョンに更新し、Assert.ThrowsAsyc関数を使用できました。

まさに私が探していたもの。 ありがとう。

このページは役に立ちましたか?
0 / 5 - 0 評価