いくつかの単体テストをセットアップし、Rhino Mocksを使用して、テスト対象のオブジェクトを設定しています。 m笑されているものの1つはTask<HttpResponseMessage>
。テスト対象のロジックには、非同期応答を取得するHttpClient
への呼び出しが含まれているためです。
だから私はこのようなモックのセットアップを始めました:
var httpClient = MockRepository.GenerateMock<HttpClient>();
var taskFunc = MockRepository.GenerateMock<Func<HttpResponseMessage>>();
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
var response = MockRepository.GenerateMock<HttpResponseMessage>();
httpClient.Stub(c => c.PostAsJsonAsync<IEnumerable<LogMessage>>(Arg<string>.Is.Anything, Arg<IEnumerable<LogMessage>>.Is.Anything)).Return(responseTask);
responseTask.Stub(t => t.Result).Return(response);
response.Stub(r => r.IsSuccessStatusCode).Return(true);
(テストの「アクト」ステップは、テスト対象のオブジェクトをインスタンス化し、httpClient
にフィードし、そのメソッドを実行することです。「アサート」は、モックを介して予期されるメソッド呼び出しが行われたことを確認しますそれらの上に。)
デバッガーでこれをステップ実行すると、この行に無期限のハングがあります。
responseTask.Stub(t => t.Result).Return(response);
Rhino MocksやC#非同期の経験はあまりないので、明らかなことを見落としているかもしれません。もちろん、目標は、.Result
プロパティはresponse
モックを返します。しかし、私の試み自体がおそらく.Result
それはたぶん単なるモックだから無期限に待つと思うだろうか?
これを整理する正しい方法は何ですか?基本的に、オブジェクトに模擬HttpClient
を提供し、特定の引数を使用してメソッドが呼び出されたことをアサートする必要があります。
最も単純なことは、期待される結果で完了したタスクを返すことです。
var responseTask = Task.FromResult(response);
これがハングする理由は、モックされたタスクが開始されないために、指定されたfuncが実行されないためだと思います。テストで開始できます:
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
responseTask.Start();
ただし、完了/失敗/キャンセルされたタスクを直接簡単に作成できるため、タスクをモックする理由はありません。