3

次のような単体テスト(MSTestを使用)があります。

[TestMethod]
public void MyTest()
{
    var viewModel = new MyViewModel();
    viewModel.Run();
    //Assert something here
}

Run は void を返す非同期メソッドです。

Run次のように実装されているとしましょう:

public async void Run()
{
    //Show a busy indicator here

    try
    {
        var result = await myAsyncModelClass.LongRunningOperation();

        //Use the results here
    }
    finally
    {
        //Hide the busy indicator here
    }
}

myAsyncModelClass.LongRunningOperation()、それ自体は非同期メソッドでTask<T>あり、T は ViewModel が関心のある結果です。

私の問題は、テストがメソッドを非同期で実行しているため、メソッドが完了Runする前にアサーションが呼び出されることです。Runアサーションが失敗するため、ブレークポイントを設定しても、最終ブロックに到達しないのは奇妙です。Runメソッドを単体テストできるように同期を維持するにはどうすればよいですか?

の単体テストもありますが、タスクを返すのmyAsyncModelClass.LongRunningOperation()で呼び出すだけです。Task<T>.Wait()これにより、単体テスト時に同期が行われます。

また、言及したいのはRun()、MVVM フレームワークによって魔法のように ICommand によって呼び出されることです。 void戻り型が必要な場合とそうでない場合があるため、試してみる必要があります。

4

2 に答える 2

15

非同期メソッドには、「戻る」ためのコンテキストが必要です。MSTests はスレッド プールで実行されるため、既定では、非同期メソッドはすべてスレッド プール スレッドでも続行されます (MSTest メソッドはブロックされません)。

(C# Testing) Unit Testingサンプル (Async CTP インストール ディレクトリ内) の下に、というタイプがあり、次のGeneralThreadAffineContextように使用できます。

[TestMethod]
public void MyTest()
{
  MyViewModel viewModel = null;
  GeneralThreadAffineContext.Run(() =>
  {
    viewModel = new MyViewModel();
    viewModel.Run();
  });
  //Assert something here
}

特定の WPF および WinForms コンテキストもありますが、スレッド アフィン コンテキストは一般的な ViewModels (を明示的に使用しないDispatcher) で機能するはずです。

2012 年 2 月 5 日更新: ViewModel メソッドを return に変更できる場合は、新しいAsyncUnitTests ライブラリTaskという別のオプションがあります。その NuGet パッケージをインストールし、 に変更すると、非同期単体テストをより自然に記述できます。TestClassAsyncTestClass

[TestMethod]
public async void MyTest()
{
  MyViewModel viewModel = new MyViewModel();
  await viewModel.Run();
  //Assert something here
}

2012 年9 月 4 日更新: Visual Studio 2012 にはasync単体テストが含まれているため、AsyncUnitTestsライブラリはもう必要ありません。

[TestMethod]
public async Task MyTest()
{
  MyViewModel viewModel = new MyViewModel();
  await viewModel.Run();
  //Assert something here
}
于 2011-08-31T18:16:58.500 に答える
3

Visual Studio 2012 以降、MSTest は非同期テスト メソッドをサポートしています。void ではなく Task を返す必要があることを覚えておいてください。

[TestMethod]
public async Task MyTest()
{
  MyViewModel viewModel = new MyViewModel();
  await viewModel.Run();
  //Assert something here
}
于 2012-07-15T13:26:53.677 に答える