6

APM (BeginXxx, EndXxx) パターンの非同期メソッドがいくつかあるとします (呼び出している WCF サービス プロキシの一部として):

public interface ISomeService
{
    IAsyncResult BeginSomeMethod(int num, AsyncCallback callback, object state);
    int EndSomeMethod(IAsyncResult ar);
}

私の実際のコードでは、 を使用しTask.Factory.FromAsyncてタスクを作成し、.net 4.5 で導入された新しい async/await パターンを使用してこのタスクを待機しています。

クラスをテストしたいので、モック、begin メソッド、end メソッド、および戻り値を受け取り、必要な戻り値を最終的に返すようにモックをセットアップするメソッドを作成する必要があります。

使用例:

SetupAsync(mock, mocked => mocked.BeginSomeMethod, mocked=> mocked.EndSomeMethod, 7);

これにより、任意の int 引数を持つ非同期フローが 7 を返します。moq でそのようなことを達成する方法がわかりません。

4

1 に答える 1

6

まず、 を使用して、ベースの非同期 WCF プロキシTaskWsdlImportExtensionを作成することをお勧めします。TaskVS2012 はデフォルトでこれを行いますが、VS2010+AsyncCTP では自分で設定する必要があります。TaskAPIに対して単体テストを行う方が簡単です。

Begin/に対して単体テストを行いたい場合は、ベースのモックを使用して/エンドポイントを公開Endするのが最も簡単な方法だと思います。私のAsyncExライブラリのメソッドは、 を囲む/メソッド ラッパーを提供します。または、これらの種類のラッパーの作成に関する Stephen Toub のブログ投稿を参照できます。TaskBeginEnd[AsyncFactory|AsyncFactory<T>].[ToBegin|ToEnd]BeginEndTask

から単純な完了済みタスクを取得するTask.FromResultか、次の構成を使用して非同期的に完了したタスクを強制することができます。

Task.Run(async () => { await Task.Yield(); return 7; });

(非同期 CTP に相当するものは次のようになります):

TaskEx.RunEx(async () => { await TaskEx.Yield(); return 7; });

これをMoqに結び付ける方法が完全にはわかりません。繰り返しますが、ベースの API は/Taskよりもモックしやすいと思います。/には独自の特別なセマンティクスがあります (正しい を渡す必要がある、各 に対して正確に 1 回呼び出す必要があるなど)。そのため、さらにテストする必要があります。BeginEndBeginEndIAsyncResultEndBegin

于 2012-06-30T14:53:43.910 に答える