77

非同期メソッドを備え、オブジェクトを返し、キーワードTask<>でマークされた ApiController を備えた ASP.NET Web API アプリケーションがあります。async

public class MyApiController : ApiController
{
    public async Task<MyData> GetDataById(string id)
    {
        ...
    }
}

ApiController の非同期メソッドの NUnit テストを作成するにはどうすればよいですか? 別のテスト フレームワークを使用する必要がある場合は、それも受け入れます。私は .NET 単体テスト全般にかなり慣れていないので、ベスト プラクティスを学ぶことに興味があります。

4

5 に答える 5

21

タスクを返す非同期メソッドをテストするためのサポートが NUnit 2.6 に組み込まれていないようです。現在私が見ることができる最良のオプションは、Visual Studio 独自の UnitTesting フレームワークまたは xUnit.net を使用することです。どちらも非同期テストをサポートしているためです。

Visual Studio UnitTesting フレームワークを使用すると、次のような非同期テストを作成できます。

using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TestAsyncMethods
{
    [TestMethod]
    public async Task TestGetBinBuildById()
    {
         ...
         var rslt = await obj.GetAsync();
         Assert.AreEqual(rslt, expected);
    }
}
于 2012-09-03T12:47:13.250 に答える
6

NUnit 2.6 シリーズは、それ以前のものと同様に、.NET 2.0 フレームワークを対象として構築されていることに注意してください。したがって、NUnit は、.NET 2.0 をターゲットとするアセンブリで、自分でコーディングできるのと同じことしか実行できません。

具体的には、テスト メソッドを非同期としてマークし、 NUnit がそれに対して特別なことを行うことを期待することはできません。

ただし、次のことができます。

  • テスト用に .NET 4.5 をターゲットにします。NUnit はそれらを別のプロセスで実行します。
  • テストでawaitを使用して、非同期メソッドの呼び出しの結果を待ちます 。

上記のどちらも、非同期テストの実行を望んでいる場合は提供しません。非同期操作が完了するのを待っている間、他のテストは実行されません。

別のオプションは、NUnitLite を使用することです。NUnitLite 0.8 は [Asynchronous] 属性をサポートします。これにより、非同期テストが完了している間、他のテストを続行できます。この属性の利点は、.NET 2.0 から 4.0 で非同期テストを実行できることです。

現在、NUnitLite の .NET 4.5 ビルドはありませんが、まもなく追加される予定であり、その環境で [Asynchronous] オプションを使用する変更に取り組んでいます。現時点では、.NET 4.5 のソース コードを簡単にダウンロードして再コンパイルできます。

将来的には、複数のスレッドまたは複数のプロセスでのテストの一般的な並列実行とともに、非同期メソッドを完全にサポートするために NUnit 3.0 に注目してください。

于 2012-09-28T15:48:45.127 に答える
4

メソッドの一部を に変換中ですasync。これを NUnit で動作させるのは非常に簡単です。

テスト メソッドを非同期にすることはできません。ただし、Task Parallel Library のすべての機能にアクセスすることはできますが、awaitキーワードをテスト メソッドで直接使用することはできません。

私の例では、メソッドがありました:

public string SendUpdateRequestToPlayer(long playerId)

そして、次のようにNUnitでテストされました:

string result = mgr.SendUpdateRequestToPlayer(player.Id.Value);
Assert.AreEqual("Status update request sent", result);
mocks.VerifyAll();

メソッドSendUpdateRequestToPlayerを非同期に変更したので、

public async Task<string> SendUpdateRequestToPlayer(long playerId)

Waitタスクを完了するには、テストを次のように変更するだけで済みました。

Task<string> task = mgr.SendUpdateRequestToPlayer(player.Id.Value);
task.Wait(); // The task runs to completion on a background thread
Assert.AreEqual("Status update request sent", task.Result);
mocks.VerifyAll();
于 2012-09-25T04:31:39.823 に答える
2

それは本当に彼らが何をしているかに依存します. 通常、それらは aまたは類似のものを提供するのものに依存します。Task<T>その場合、これらすべてをきめの細かい方法で制御できる偽の依存関係を提供できる場合があります。私はプロトタイプの「タイムマシン」を手に入れました。これにより、特定の人為的な時間に完了するようにタスクを事前にプログラムし、時間を進めてアサーションを実行できます。それについてのブログ投稿があり、役に立つかもしれません。私が言うように、これはプロトタイプにすぎず、すべてのシナリオに適しているわけではありませんが、あなたには合うかもしれません.

Stephen Cleary も、単体テストに関するいくつかのブログ投稿 ( 12 ) を行っており、少し異なるアプローチを採用しており、便利なNuGet パッケージも紹介しています。

ただし、基本的なアプローチは通常と同じです。メソッドに異なる入力 (および依存関係の出力) を与えて、結果をテストします。非同期でそれを達成するのは間違いなく難しいですが、実行可能です。

于 2012-08-30T07:39:25.190 に答える