| 財産 | 価値 |
|---|---|
| ルール識別子 | 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
詳細については、「 コード分析の警告を抑制する方法」を参照してください。
.NET