MSTEST0049: Flow TestContext キャンセル トークン

Property Value
ルール識別子 MSTEST0049
Title Flow TestContext キャンセル トークン
Category Usage
修正が破壊的であるか非破壊的であるか Non-breaking
既定で有効 Yes
既定の重大度 Info
バージョン で導入された 3.10.0
コード修正はありますか Yes

Cause

呼び出されたメソッドにCancellationTokenを受け入れるパラメーターまたはオーバーロードがある場合、テスト コンテキスト内のメソッド呼び出しでは、TestContextから使用できるCancellationTokenは使用されません。

ルールの説明

テスト メソッドで TestContext を使用できる場合は、その CancellationToken を非同期操作にフローする必要があります。 これにより、タイムアウトが発生したときに協調的な取り消しが可能になり、リソースの適切なクリーンアップが保証されます。 TestContextキャンセル トークンは、タイムアウト属性と共に協調キャンセルを使用する場合に特に重要です。

このルールは、次の場合にトリガーされます。

  • メソッド呼び出しには、明示的に指定されていない省略可能な CancellationToken パラメーターがあります。
  • メソッド呼び出しには、 CancellationToken を受け入れるオーバーロードがありますが、代わりに取り消し不可能なオーバーロードが使用されます。

違反を修正する方法

指定されたコード修正プログラムを使用して、CancellationTokenからキャンセルをサポートするメソッド呼び出しにTestContextを自動的に渡します。 メソッド呼び出しを手動で更新して、 TestContext.CancellationToken をパラメーターとして含めることもできます。

例: TestContext プロパティ

次のコードは、 Task.DelayHttpClient.GetAsyncCancellationToken を受け入れるが、何も渡されないため、MSTEST0049をトリガーします。

[TestClass]
public class MyTestClass
{
    public TestContext TestContext { get; set; }

    [TestMethod]
    public async Task TestMethod()
    {
        using var client = new HttpClient();
        // MSTEST0049: these calls accept a CancellationToken but none is passed
        await Task.Delay(1000);
        var response = await client.GetAsync("https://example.com");
    }
}

修正は、各呼び出しに TestContext.CancellationToken を渡すことです。

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestClassCancellationToken
{
    // MSTest automatically sets the TestContext property before each test runs.
    // MSTest.Analyzers includes a diagnostic suppressor that removes CS8618
    // (non-nullable property uninitialized) for this property.
    public TestContext TestContext { get; set; }

    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public async Task MyAsyncTest()
    {
        using var client = new HttpClient();
        var response = await client.GetAsync(
            "https://example.com", TestContext.CancellationToken);

        Assert.IsTrue(response.IsSuccessStatusCode);
    }
}

例: コンストラクターの挿入 (MSTest 3.6 以降)

コンストラクターの挿入では、 _testContext フィールドを使用してキャンセル トークンにアクセスします。

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestClassCancellationTokenCtor
{
    private readonly TestContext _testContext;

    public TestClassCancellationTokenCtor(TestContext testContext)
    {
        _testContext = testContext;
    }

    [TestMethod]
    [Timeout(5000, CooperativeCancellation = true)]
    public async Task MyAsyncTest()
    {
        using var client = new HttpClient();
        var response = await client.GetAsync(
            "https://example.com", _testContext.CancellationToken);

        Assert.IsTrue(response.IsSuccessStatusCode);
    }
}

警告を抑制するタイミング

特定の操作の取り消しを意図的にサポートしない場合や、テストが取り消された場合でも操作を続行する必要がある場合は、この警告を抑制します。

警告を抑制する

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

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

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

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

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