async/await キーワードが使用されていない場合、非同期ユニットテストが失敗するのはなぜですか? 質問する

async/await キーワードが使用されていない場合、非同期ユニットテストが失敗するのはなぜですか? 質問する

によるとこの議論次の 2 つの方法の間に違いはありません。

public async Task Foo()
{
    await DoSomethingAsync();
}

public Task Foo()
{
    return DoSomethingAsync();
}

実際、非常に単純なメソッドの場合、呼び出しはそれなしオーバーヘッドを削減できるため、async/await キーワードが推奨されます。

ただし、これはユニット テストでは常に機能するとは限りません。

MSテスト

[TestClass]
public class AsyncTest
{
    [TestMethod]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [TestMethod]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}

ユニット

[TestFixture]
public class AsyncTest
{
    [Test]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Test]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}

Xユニット

public class AsyncTest
{
    [Fact]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Fact]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
  • いずれの場合もTest1合格です。
  • MSTest では、Test2テスト ランナーに表示されますが、実行されません。
  • NUnit では、Test2次のメッセージが表示されて無視されます:

    テストメソッドには非 void 戻り型がありますが、結果は期待されません

  • XUnit ではTest2合格です。

タスクはすべてのケースで待機可能なので、asyncNUnit および MSTest テスト ランナーに影響を与えるキーワードの何が問題なのでしょうか。おそらくリフレクションの問題でしょうか。

ベストアンサー1

Taskこれらのテストランナーは、メソッドが本当に返されるかどうかを確認するためにリフレクションを使用しているようです。非同期メソッド。メソッドの動作が異なるということではありませんもし実行されたら- しかし、それらは実行されていないだけです。

それは次のように言っているようなものです:

public string Name { get; set; }

は以下と同等です:

private string name;
public Name { get { return name; } set { name = value; } }

動作の点では論理的には同じですが、よくよく考えてみると違いがわかります。この特定のケースでは、他にも微妙な違いがありますが、同じ一般原則が適用されます。

現在のNUnitコード(この記事の執筆時点)では、検出は次のようになっているようです。AsyncInvocationRegion.cs

確かに少なくとも普通でないTask非同期メソッドを使用せずに butを返す単体テストを書くことはできますが、決して不可能ではありません。

おすすめ記事