2016-04-07 7 views
7

私は単純なhttpクライアントを書く必要があります。私のクラスの単体テストをすることは素晴らしいことかもしれません。しかし、私は適切でテスト可能なクラスを書く方法を知らない。例えばネットワーククライアントのユニットテストの作成方法は?

、私はこのようなクライアントを持っている:

class HTTPClient 
{ 
public: 
    HTTPCLient(const std::string& host, const std::string& port): session(host, port) {} 

    void send() 
    { 
     session.sendRequest(someRequest); 
     Response response = session.receiveResponse(); 
     // ... 
    } 

private: 
    SomeLibrary::ClientSession session; 
}; 

sendメソッドをテストする方法(私は本当に私が欲しいものを送っていることを)?私はそれを嘲笑することはできません。私はHTTPClientがコンストラクタ内のSomeLibrary::ClientSessionオブジェクトを受け取ると書くことができます(テストではモックを渡すでしょう)が良いデザインですか?私はセッションなどの実装方法が私のクラスに隠されるべきだと思う。

ご存知ですか?

答えて

5

先日、HTTPクライアントライブラリを作成したことがありました。

HTTPクライアントライブラリをテストするために、ちょうどstd::threadのランダムポートでリッスンを開始した簡単なテストコードを書きました(localhost)。次に、クライアントに、hostportパラメータを指定してテスト要求を行うように、私のスレッドが現在リッスンしていたポートを指しています。スレッドのコードは、接続を受け付け、HTTPリクエストを読み込んで保存し、HTTPレスポンスで応答するようにプログラムされていました。

これで、クライアントの実際のリクエストとクライアントがHTTPレスポンスをどのように処理したかの両方を検証して、クライアントライブラリをテストしました。後で、このユニットテストコードを開発して、さまざまな種類のHTTPエラーと不正なHTTPレスポンスを送信し、クライアントコードがそれらの状況をどのように処理したかをテストして検証しました。

また、良いことは、alarm()コールによってすべてが保護されていたため、何かが無限ループに陥った場合、プロセス全体が最終的に自殺することになります。

これは、同じ方法で独自のコードをテストする方法です。

0

コンストラクタで抽象クライアントセッションインスタンスを注入します。単体テストでそれを模擬し、実際に実行するときは実際のインスタンスを渡します。

の文章を1つの文で黙らせることはできないと言います。次の文章では、あなたは何を意味するのですか?セッションクラスが「あなたのもの」ではない、あるいはそれを嘲笑されないということを意味するならば、それをあなたのクラスでラップしようとしました。それでを嘲笑できますか?

また、「セッションなどの実装方法が私のクラスに隠れるべきだと思う」と言います。

という前提であなたの誤謬は、あなたのクラスは、私はあなたがHTTPClient意味推測ということです、それとは関係ありません - それは、独自の実装を非表示にするセッションクラスだし、あなたならばそれも行うことができますことこれをコンストラクタのインスタンスとして渡すと、全体的に無制限の柔軟性が追加されます。

0

ソケットを使用して単純なHTTPサーバーを模倣することができます。チャンク転送やリダイレクトをまねる

1) set up a string to send from the client, take its length in before hand 
2) open a new thread with a socket in it 
3) bind the socket into some port , listen and accept new connection 
4) send the string you have setted with your http client 
5) in the socket side, read until the length you saved has reached, save that string for comparison 
6) send some pre-defined http response 
7) close the socket 
7) close the thread 
8) continue testing, you have the string which the server got, and the string which the client got, and the original strings which these was originated from 

は簡単ですが、SSLをまねることは非常に困難になります 次の擬似コードは役立つかもしれません。 openSSLまたはBoost SSLストリームで提供されるいくつかのSSLストリームでソケットをラップすることができます。

もう1つのオプションは、ローカルホスト上に既に書き込まれたHTTPサーバーを使用することです。 PythonやNode.jsで(テスト専用の)1つを書くことは、テストのタスクには非常に簡単で適切です。テストが開始される前に、サーバスクリプト(Node.jsスクリプトを使用して、簡単にsystem("node myServer.js"))をアクティブにし、テストが終了したら、そのサーバを強制終了します。

関連する問題