Wie kann ich verspotte eine externe web-Anfrage in PHPUnit?
Arbeite ich am Aufbau einer Test-suite für eine PHP - Treiben Projekt
mit Phactory, und PHPUnit. Ich bin versucht derzeit, einen unit-test ein
Funktion macht eine externe Anforderung, und ich möchte in einem mock stub
Antwort für diese Anfrage.
Hier ist ein Ausschnitt der Klasse, die ich bin versucht zu testen:
class Endpoint {
...
public function parseThirdPartyResponse() {
$response = $this->fetchUrl("www.example.com/api.xml");
//do stuff and return
...
}
public function fetchUrl($url) {
return file_get_contents($url);
}
...
Und hier ist die test-Funktion, die ich bin versucht zu schreiben.
//my factory, defined in a seperate file
Phactory::define('endpoint', array('identifier' => 'endpoint_$n');
//a test case in my endpoint_test file
public function testParseThirdPartyResponse() {
$phEndpoint = Phactory::create('endpoint', $options);
$endpoint = new EndpointQuery()::create()->findPK($phEndpoint->id);
$stub = $this->getMock('Endpoint');
$xml = "...<target>test_target</target>..."; //sample response from third party api
$stub->expects($this->any())
->method('fetchUrl')
->will($this->returnValue($xml));
$result = $endpoint->parseThirdPartyResponse();
$this->assertEquals('test_target', $result);
}
Ich kann jetzt sehen, nachdem ich versucht mein test-code, erstelle ich ein mock-Objekt
mit getMock
, und dann nie benutzen. So wird die Funktion fetchUrl
tatsächlich ausführt, was ich nicht will. Aber ich will auch noch nutzen zu können
die Phactory erstellt endpoint
- Objekt, denn es hat für alle die richtigen Felder
bevölkert von meinem Fabrik-definition.
Gibt es eine Möglichkeit für mich, um auszudrücken, eine Methode, die auf einem vorhandenen Objekt? Also ich könnte stub
fetch_url
auf die $endpoint
Endpoint-Objekt das ich erstellt habe?
Oder werde ich über das alles falsch; gibt es einen besseren Weg für mich zu unit-test
meine Funktionen, die sich auf externe web-Anfragen?
Ich habe gelesen, dass die PHPUnit-Dokumentation über "Stubbing-und Mocking-Web-Services", aber Ihre Probe-code dafür ist 40 Zeilen lang, nicht einschließlich zu definieren, Ihre eigenen wsdl. Ich bin hart gedrückt, um zu glauben, dass das der bequemste Weg für mich, dies zu behandeln, es sei denn, die guten Menschen SO stark fühlen, sonst.
Sehr zu schätzen jede Hilfe, ich habe aufgehängt wurde, auf das den ganzen Tag. Danke!!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus der Perspektive des testens, dein code hat zwei Probleme:
Mit Ihrem code wie folgt, es ist kein guter Weg, um den code zu testen. Sie könnten arbeiten mit Reflexionen, ändern Sie Ihren code und so weiter. Das problem bei diesem Ansatz ist, dass Sie nicht testen Sie Ihre eigentliche Objekt aber einige Reflexion, die ändern arbeiten mit dem test.
Wenn Sie schreiben wollen, "gute" tests, die Ihr Endgerät sollte in etwa so Aussehen:
Nun konnte man sich Spritzen, ein Nachbau des DataParser gibt einige Standard-Antwort, je nachdem, was Sie testen möchten.
Die nächste Frage wäre: Wie kann ich testen, die DataParser? Meist können Sie das nicht. Wenn es nur ein wrapper für die php-standard-Funktionen, die Sie nicht brauchen, um. Ihre DataParser sollte wirklich sehr niedrigen Niveau, so Aussehen:
Wenn Sie brauchen oder wollen, um es zu testen, könnten Sie einen Webservice, die Leben in Ihre tests und dient als eine Art "Mock", immer wiederkehrenden vorkonfigurierten Daten. Sie können dann rufen Sie die mock-url statt die Reale und die Leistungsbewertung.
file_get_contents
fühlt wie overkill für mich. Es ist eine code-änderung würde ich machen, nur um es zu testen, und das fühlt sich aus zu mir. Ich komme aus der ruby, das war die webmock Edelstein, der macht genau das, was Sie beschrieben haben, in Ihrem letzten Absatz: "erstellt ein Webservice, das Leben innerhalb Ihrer tests und dient als eine Art "Mock", immer wiederkehrenden vorkonfigurierte Daten". Statt der Codierung, mit mir ich werde gehen, das mock-Objekt der route für heute. Vielen Dank für die Gedanken!