MSTEST0064: 非同期アサーション メソッドを優先する

財産 価値
ルール識別子 MSTEST0064
タイトル 非同期アサーションメソッドを優先する
Category Usage
修正が破壊的か非破壊的か Non-breaking
既定で有効 はい
既定の重大度 情報
バージョン で導入された 4.3.0
コード修正はありますか No

この規則は、MSTest 4.3 以降で使用できます。

原因

テスト メソッドでは、Assert.Throws または Assert.ThrowsExactly を使用して、非同期であり、GetAwaiter().GetResult() を使用して非同期操作をブロックするコードによって例外がスローされることをアサートします。

ルールの説明

非同期コードが例外をスローすることをアサートする場合は、Assert.ThrowsAsync および Assert.ThrowsExactlyAsync の非同期アサーション メソッドを使用し、GetAwaiter().GetResult() で非同期操作をブロックする方法よりもそれらを優先します。 非同期コードでブロックすると、一部の同期コンテキストでデッドロックが発生する可能性があり、同等の awaitベースのアサーションよりも読みにくい場合があります。

[TestClass]
public class TestClass
{
    [TestMethod]
    public async Task Test_ThrowsOnAsyncCall()
    {
        // Violation: blocks the async call inside Assert.Throws.
        Assert.Throws<InvalidOperationException>(() => DoAsync().GetAwaiter().GetResult());
    }

    private static async Task DoAsync()
    {
        await Task.Yield();
        throw new InvalidOperationException();
    }
}

違反を修正する方法

非同期アサーション メソッドを使用して、await します。

[TestClass]
public class TestClass
{
    [TestMethod]
    public async Task Test_ThrowsOnAsyncCall()
    {
        await Assert.ThrowsAsync<InvalidOperationException>(() => DoAsync());
    }

    private static async Task DoAsync()
    {
        await Task.Yield();
        throw new InvalidOperationException();
    }
}

Assert.ThrowsExactly についても適用され、これには Assert.ThrowsExactlyAsync というカウンターパートが存在します。

どのようなときに警告を抑制するか

この警告は、包含するテスト メソッドを async にできない場合 (基底クラスまたはインターフェイス シグネチャで必要な同期テスト オーバーロードなど)、ブロック呼び出しを保持する必要がある場合に抑制できます。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable MSTEST0064
// The code that's violating the rule is on this line.
#pragma warning restore MSTEST0064

ファイル、フォルダー、またはプロジェクトのルールを無効にするには、noneでその重要度をに設定します。

[*.{cs,vb}]
dotnet_diagnostic.MSTEST0064.severity = none

詳細については、「 コード分析の警告を抑制する方法」を参照してください。