2016-04-07 17 views
7

Ich muss einfach HTTP-Client schreiben. Es könnte toll sein, Unit-Tests für meine Klasse zu haben. Aber ich weiß nicht, wie man richtige und testbare Klasse schreibt.Wie schreibt man Komponententest für Netzwerk-Client?

Zum Beispiel habe ich einen Klienten wie folgt aus:

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; 
}; 

Wie send Methode zu testen (die ich wirklich senden, was ich will)? Ich kann es nicht verspotten. Ich kann schreiben, dass HTTPClient empfängt SomeLibrary::ClientSession Objekt im Konstruktor (im Test würde ich Pseudo passieren), aber ist es ein gutes Design? Ich denke, dass die Art der Umsetzung der Sitzung usw. in meiner Klasse versteckt werden sollte.

Haben Sie eine Idee?

Antwort

5

Ich hatte Glück, eine HTTP-Client-Bibliothek neulich geschrieben zu haben.

Um die HTTP-Client-Bibliothek zu testen, schrieb ich einfach einfachen Test-Code, der eine std::thread Anhören von einigen zufälligen Port auf localhost begann. Dann sagte ich dem Client, er solle eine Testanfrage mit den Parametern host und port machen, wie in Ihrem Fall, und auf den Port zeigen, den mein Thread gerade abhob. Der Code des Threads wurde so programmiert, dass er eine Verbindung akzeptiert, eine HTTP-Anforderung liest, sie speichert und dann mit einer vordefinierten HTTP-Antwort antwortet.

Und so habe ich meine Client-Bibliothek getestet und dabei sowohl die tatsächliche Anfrage, die der Client gesendet hat, als auch die Verarbeitung der vordefinierten HTTP-Antwort durch den Client überprüft. Später entwickelte ich diesen Komponententestcode, um verschiedene Arten von HTTP-Fehlern und fehlerhaften HTTP-Antworten zu senden, um zu testen und zu überprüfen, wie der Clientcode diese Situationen behandelte.

Und für eine gute Maßnahme wurde die ganze Sache von einem alarm() Ruf geschützt, wenn also etwas in einer Endlosschleife oder so stecken bleibt, wird der gesamte Prozess schließlich Selbstmord begehen.

Und so können Sie auch Ihren eigenen Code testen.

0

Inject eine abstrakte Clientsitzungsinstanz im Konstruktor. Mock es in Unit-Tests und übergeben Sie eine echte Instanz, wenn Sie real laufen.

Sie sagen, Sie können nicht es in einem Satz spotten und im nächsten Satz Sie sagen, Sie können - was meinst du? Wenn Sie meinen, dass die Sitzungsklasse nicht "Ihre" ist oder dass sie nicht davon abgeleitet werden kann, auf diese Weise verspottet zu werden, haben Sie dann versucht, sie in eine Klasse von Ihnen zu verpacken, so dass sie verspottet werden kann?

Auch Sie sagen "Ich denke, dass die Art der Umsetzung der Sitzung usw. durch meine Klasse versteckt werden sollte."

in dieser Annahme Ihr Irrtum ist, dass Ihre Klasse, ich denke du meinst HTTPClient, hat nichts damit zu tun - es ist die Sitzungs-Klasse, die ihre eigene Implementierung verstecken sollte, und dass es kann auch, wenn Sie tun übergeben Sie es als eine Instanz im Konstruktor, die insgesamt auch unendliche Flexibilität hinzufügt.

0

können Sie einfachen HTTP-Server mit einem Sockel nachahmen. der folgende Pseudo-Code kann helfen:

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 

nachahmt segmentierte Übertragungs und Umleitungen ist einfach, aber SSL Nachahmen kann ziemlich schwierig sein. Sie können Ihren Socket mit einem SSL-Stream versehen, der mit openSSL oder Boost SSL-Stream bereitgestellt wird.

Eine andere Option ist die Verwendung bereits geschriebener HTTP-Server auf dem lokalen Host. eine (nur zum Testen) in Python oder Node.js zu schreiben, ist ziemlich einfach und für diese Testaufgabe geeignet. Bevor der Test gestartet wird, aktivieren Sie das Server-Skript (mit Node.js-Skript, es ist einfach wie system("node myServer.js")) und wenn der Test abgeschlossen ist, töten Sie diesen Server.