2016-04-20 3 views
3

hat Ich implementiere eine API, die unterschiedliche Kommunikation zwischen der Anwendung und dem Internet (10, Socket.IO, WebClient http Anfragen ..) der TDD-Weg. Bis jetzt war ich in der Lage, Einheitentests für alle Methoden zu schreiben, weil ich alle Aufrufe einkapseln konnte, um sie zu verspotten. Zum Beispiel, wenn eine Methode eine HTTP-Anfrage über die System.Net.Webclient verwendet, hatte ich die volle Kontrolle über die HttpWebResponse.Wie man eine Third-Party-lib verspottet, die nur konkrete Klassen mit Moq, Xunit

Jetzt für die nächste Anfrage habe ich müssen verwenden Sie eine Third-Party-Bibliothek, die am Ende sendet nur HTTP-Anfragen. Das Problem ist, dass ich keine Ahnung habe, wie ich das vortäuschen kann, da alle Klassen konkrete Klassen sind. Zur Vereinfachung ist hier ein kurzes Beispiel.

Dies wäre die Methode, die ich Unit-Test wollen. Es sendet eine Anforderung und ruft den Rückruf in Abhängigkeit von der Antwort von der Anfrage des Rückwegs:

public void MyMethodIwantToUnitTest(string data, Action<SomeData> callback) 

Der Dritte lib ganz gerade nach vorn, können Sie Ihre Anfrage mit einem Rückruf bauen und sie versenden:

HTTPRequest request = new HTTPRequest(new Uri("https://google.com"), onRequestFinished); 
request.Send(); 

void OnRequestFinished(HTTPRequest request, HTTPResponse response) 
{ 
// here would be basically the logic I want to test 
} 

Was ich brauche, ist irgendwie die onRequestFinished in meinem Einheitstest anrufen, mit einem Schein HTTPResponse (HttpResponse ist nur eine konkrete Klasse). Und ich habe keine Ahnung, ob das überhaupt möglich ist.

+7

http://stackoverflow.com/a/150480/126014 –

+0

Das ist eigentlich, was ich vorher gemacht habe, aber ein Problem ist, dass die Daten, die ich brauche, von 'HTTPResponse' (Daten, Ausnahme) schreibgeschützt ist, damit ich ' t Erstellen Sie eine Instanz davon und füllen Sie sie mit Testdaten. – zlZimon

+3

Da Sie TDD ausführen, würde ich empfehlen, dass Sie die SOLID-Prinzipien anwenden und die Schnittstelle definieren, die der * Client * braucht, anstatt die Abhängigkeit bereitzustellen. Das wird Ihnen wahrscheinlich erlauben, eine kleinere Fläche zu definieren. Sobald Sie diese (oder diese) Schnittstellen definiert haben, schreiben Sie die notwendigen Adapter für diese Drittanbieter-Bibliothek. –

Antwort

0

Hier ist meine Sicht darauf. Der Code-Client verwendet IResource.Fetch (url, Rückruf)

Verwenden Sie einen Rahmen spöttisch ein IResource Mock & aufrufen, um den Rückruf mit den erforderlichen Antwort/Daten erstellen, wann immer es genannt wird. Stecken Sie es in den aufrufenden Code als Abhängigkeit.

Der Code im letzten Snippet in der Frage wird in die echte IResource.Fetch-Implementierung verschoben. Da dies an der Grenze ist, verwende ich normalerweise einen Integrationstest - der gegen das reale Netzwerk läuft. Wenn ich einen Typ habe, dessen Aufgabe es ist, etwas auf Platte/Datenbank zu serialisieren, verifiziere ich das mit einem Integrationstest, der den vollen Zyklus durchläuft. Annahmen:

  1. Es gibt nicht viel Logik in dieser Art ist - es ist ein Durchgang durch auf die konkrete Bibliothek.
  2. Sobald sie umgesetzt wird, dieser Code wird nicht häufig geändert werden

Langsamer. Bessere Sicherheit und umgeht auch das Problem der nicht testbaren Bibliothek. Ich markiere sie mit einer 'Integration' Kategorie und führe diese Tests einmal vor dem Commit durch, nicht nach jedem Editieren.

Verwandte Themen