TL; DR: Ihre Schließung Argument Mockery::on
Bedürfnisse true
oder false
zurückzukehren.
Die längere Erklärung:
Das Problem ist, mit Ihrem Anruf Mockery::on
. Diese Methode verwendet eine Schließung (oder eine andere Funktion) als Argument. Je nachdem, ob das Argument für die Schließung den Test erfüllt, sollte diese Schließung wahr oder falsch sein.
Das ist eine ziemlich verwirrende Erklärung war, so werde ich :-)
Betrachten Sie die folgende Erwartung ein Beispiel versuchen:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with("myargument")
->once()
->andReturn("something");
Diese Erwartung, wenn das System im Test erfüllt werden (SUT)
nennt
$x = $myclass->mymethod("myargument");
und der Wert von $x
wird "etwas".
Jetzt haben die Entwickler von Michery erkannt, dass es einige Erwartungen gibt, die sie einfach nicht erfüllen können. Zum Beispiel (und das ist etwas, das mich für eine Weile stolperte), eine Schließung. Es stellt sich heraus, dass eine Schließung in PHP eine Art komplizierte interne Ressource ist, und selbst wenn Sie zwei Schließungen identisch definieren, werden sie nicht identisch sein. Bedenken Sie:
$x = function($v){ echo $v; };
$y = function($v){ echo $v; };
echo $x==$y ? "True" : "False";
wird den Wert "False" widergeben. Warum? Von meinem begrenzten Verständnis des Themas hat es etwas mit der internen Darstellung von Closure-Objekten in PHP zu tun. Also, wenn Sie eine Methode verspotten, die eine Schließung als Argument erfordert, gibt es keine Möglichkeit, die Erwartung zu erfüllen.
Die Mockery::on()
Methode bietet einen Weg um dies. Mit dieser Methode können Sie eine (andere) Sperrung an Mockery übergeben, die als wahr oder falsch bewertet wird, je nachdem, ob Ihre Tests zeigen, dass Sie die richtigen Argumente haben. Ein Beispiel:
Stellen Sie sich vor, dass eine Schließung als Argument erfordert. Im Folgenden wird immer scheitern, unabhängig davon, was Schließung Sie im SUT zu mymethod
passieren:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with(function($v){ echo $v; })
->once()
->andReturn("something");
Dies liegt daran, Mockery wird das Argument in dem SUT (a Verschluss) auf die oben (function($v){ echo $v; }
) definiert Schließung geführt vergleichen und Dieser Test wird fehlschlagen, auch wenn die beiden Schließungen identisch definiert sind.
Mit Mockery::on()
, können Sie den Test wie folgt umschreiben:
$mock = Mockery::mock("myclass");
$mock->shouldReceive("mymethod")
->with(Mockery::on(function($value){
return is_callable($value);
})
->once()
->andReturn("something");
Nun, wenn Mockery die Erwartung auswertet, wird die Schließung als Argument an Mockery::on()
geben nennen. Wenn es true
zurückgibt, wird Motelery die erwartete Erwartung berücksichtigen; Wenn es false
zurückgibt, wird Mockery es als gescheitert betrachten.
Die Erwartung in diesem Beispiel wird für jede Schließung übergeben, die an myclass::mymethod
übergeben wird, die wahrscheinlich nicht spezifisch genug ist. Sie möchten wahrscheinlich einen anspruchsvolleren Test, aber das ist die Grundidee.
/facepalm .... Ich weiß, es muss wahr oder falsch zurück und vollständig ausgeschlossen werden. Du hast vollkommen recht! Danke für die ausführliche Erklärung, +1! – Webnet
Ich wurde in den letzten Wochen mehrmals von demselben Problem überrascht. Ich denke, ich werde das Lesezeichen setzen, damit ich es nicht immer wieder lösen muss :-) – Kryten
Warum hat das nur 3 upvotes? – DanSingerman