[解決済み】Moqを使用してユニットテストの非同期メソッドをモック化する
質問
ウェブページを作成するサービスのメソッドをテストしています。
API
を呼び出します。通常の
HttpClient
は、ウェブサービス (ソリューション内の別のプロジェクトにあります) をローカルで実行しても、ユニットテストでは問題なく動作します。
しかし、変更をチェックインすると、ビルドサーバーはウェブサービスにアクセスできないので、テストは失敗します。
この問題を回避するために、ユニットテストに
IHttpClient
インターフェイスを実装し、私のアプリケーションで使用するバージョンを実装しています。ユニットテストでは、非同期ポストメソッドをモック化したバージョンを作成します。ここで、問題が発生しました。私はOKを返したいのです。
HttpStatusResult
この特定のテストのために。別の同じようなテストでは、悪い結果を返します。
テストは実行されますが、完了することはありません。awaitのところでハングアップしてしまいます。私は非同期プログラミング、デリゲート、そしてMoqそのものが初めてで、しばらくSOやGoogleで検索して新しいことを学んでいましたが、まだこの問題を乗り越えることができないようです。
以下は、私がテストしようとしているメソッドです。
public async Task<bool> QueueNotificationAsync(IHttpClient client, Email email)
{
// do stuff
try
{
// The test hangs here, never returning
HttpResponseMessage response = await client.PostAsync(uri, content);
// more logic here
}
// more stuff
}
これが私のユニットテストのメソッドです。
[TestMethod]
public async Task QueueNotificationAsync_Completes_With_ValidEmail()
{
Email email = new Email()
{
FromAddress = "[email protected]",
ToAddress = "[email protected]",
CCAddress = "[email protected]",
BCCAddress = "[email protected]",
Subject = "Hello",
Body = "Hello World."
};
var mockClient = new Mock<IHttpClient>();
mockClient.Setup(c => c.PostAsync(
It.IsAny<Uri>(),
It.IsAny<HttpContent>()
)).Returns(() => new Task<HttpResponseMessage>(() => new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
bool result = await _notificationRequestService.QueueNotificationAsync(mockClient.Object, email);
Assert.IsTrue(result, "Queue failed.");
}
何が間違っているのでしょうか?
よろしくお願いします。
解決方法は?
タスクを作成しても開始しないので、完了しない。しかし、ただタスクを開始するだけでなく、代わりに
Task.FromResult<TResult>
これは、すでに完了したタスクを表示します。
...
.Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
この方法では実際の非同期をテストしないことに注意してください。そうしたい場合は、もう少し手間をかけて
Task<T>
しかし、それはまた別の機会に。
のフェイクを使用することも検討した方がいいかもしれません。
IHttpClient
は、すべてをモック化するのではなく、必要な頻度に依存します。
関連
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】WebResource.axdとは何ですか?
-
[解決済み] C#で同期メソッドから非同期メソッドを呼び出すには?
-
[解決済み] TDDのためのJavaScriptユニットテストツール
-
[解決済み] Moqでメソッドが呼び出されていないことを確認する方法は?
-
[解決済み] C#でawaitを使わずに非同期メソッドを安全に呼び出す方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】Nullableオブジェクトは値を持たなければならない?