[解決済み] ユニットテストでのHttpClientのモック化
質問
ユニットテストで使用するためにコードをラップしようとすると、いくつかの問題が発生します。その問題とは、次のようなものです。私はインターフェイス
IHttpHandler
:
public interface IHttpHandler
{
HttpClient client { get; }
}
そして、それを利用したクラス。
HttpHandler
:
public class HttpHandler : IHttpHandler
{
public HttpClient client
{
get
{
return new HttpClient();
}
}
}
そして、その後に
Connection
クラスで、クライアントの実装を注入するために simpleIOC を使用しています。
public class Connection
{
private IHttpHandler _httpClient;
public Connection(IHttpHandler httpClient)
{
_httpClient = httpClient;
}
}
そして、このクラスがあるユニットテストプロジェクトがあります。
private IHttpHandler _httpClient;
[TestMethod]
public void TestMockConnection()
{
var client = new Connection(_httpClient);
client.doSomething();
// Here I want to somehow create a mock instance of the http client
// Instead of the real one. How Should I approach this?
}
さて、当然ながら
Connection
クラスは、私のバックエンドからデータ (JSON) を取得します。しかし、このクラスのユニットテストを書きたいのですが、明らかに本物のバックエンドに対するテストではなく、モックされたものに対するテストを書きたいと思っています。これに対する良い答えをググってみましたが、あまり成功しませんでした。以前、Moqを使ってモックを作ったことがありますが、次のようなものには使ったことがありません。
HttpClient
. この問題にどのようにアプローチすればよいのでしょうか?
どのように解決するのですか?
あなたのインターフェイスは具体的な
HttpClient
したがって、このインターフェイスを使用するすべてのクラスは、このインターフェイスに結びつきます。
HttpClient
はどのインターフェースも継承していないので、自分で書く必要があります。そこで
デコレータのような
のパターンがあります。
public interface IHttpHandler
{
HttpResponseMessage Get(string url);
HttpResponseMessage Post(string url, HttpContent content);
Task<HttpResponseMessage> GetAsync(string url);
Task<HttpResponseMessage> PostAsync(string url, HttpContent content);
}
そして、あなたのクラスは次のようになります。
public class HttpClientHandler : IHttpHandler
{
private HttpClient _client = new HttpClient();
public HttpResponseMessage Get(string url)
{
return GetAsync(url).Result;
}
public HttpResponseMessage Post(string url, HttpContent content)
{
return PostAsync(url, content).Result;
}
public async Task<HttpResponseMessage> GetAsync(string url)
{
return await _client.GetAsync(url);
}
public async Task<HttpResponseMessage> PostAsync(string url, HttpContent content)
{
return await _client.PostAsync(url, content);
}
}
これらすべてにおいて重要なのは
HttpClientHandler
は自分自身の
HttpClient
を実装したクラスを複数作成することができます。
IHttpHandler
をさまざまな方法で作成します。
この方法の主な問題は、事実上、他のクラスのメソッドを呼び出すだけのクラスを書いていることです。
を継承しています。
からの
HttpClient
(参照
Nkosiの例
私のやり方よりずっといい方法です)。もし
HttpClient
はモックできるインターフェイスを持っていますが、残念ながらそれはありません。
この例は
ではない
しかし、その金字塔は
IHttpHandler
に依存しています。
HttpResponseMessage
に属している。
System.Net.Http
名前空間以外の実装が必要な場合、その実装は
HttpClient
に変換するために、何らかのマッピングを行う必要があります。
HttpResponseMessage
オブジェクトを作成します。これはもちろん、以下のような問題だけです。
複数の実装を使用する必要がある場合
の
IHttpHandler
が、そうではなさそうなので、この世の終わりというわけではありませんが、考えておく必要があります。
とにかく、単純にモック
IHttpHandler
を気にすることなく、具体的な
HttpClient
クラスが抽象化されているためです。
をテストすることをお勧めします。 非同期 これらは非同期メソッドを呼び出しますが、非同期メソッドのユニットテストを気にする必要はありません。 こちら
関連
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
解決済み] 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#.
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み] フェイク、モッキング、スタビングの違いとは?
-
[解決済み] プライベートメソッドのユニットテストはどのように行うのですか?
-
[解決済み】PHPUnitでprotectedメソッドをテストするためのベストプラクティス
-
[解決済み】Moqを使用してユニットテストの非同期メソッドをモック化する
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C#で四捨五入する方法
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】 C# 条件演算子エラー 代入、call、increment、decrement、await、new object 式のみ文として使用可能です。
-
[解決済み】Nullableオブジェクトは値を持たなければならない?