Ich benutze PHPUnit ~5.2
und PHP ~7.0.0
.Verwendung expectException und ein Spion in PHPUnit
Ich habe eine Klasse, die ein Repository umschließt, die Ausnahmen abfängt, einen Logger aufruft und dann die Ausnahme erneut ausliest.
public function storeDonation(Donation $donation) {
try {
$this->repository->storeDonation($donation);
}
catch (StoreDonationException $ex) {
$this->logger->log($this->logLevel, $ex->getMessage(), [ 'exception' => $ex ]);
throw $ex;
}
}
In meinen Tests habe ich ein Spion für den Logger erstellt, ich kann so sehen, welche, wo auf die Logging-Funktionen gemacht aufruft. Dieser Spion ist ein dedizierter Testdoppel, der NICHT über die PHPUnit Mocking-API erstellt wurde. Das Problem, auf das ich gestoßen bin, würde nicht auftreten, wenn ich die PHPUnit-Mocking-API verwende, aber ich frage hier nicht nach Feedback für diese Entscheidung.
Das Testverfahren, wo ich in Probleme renne hat einige Code-Setup, dann es einen Aufruf an PHPUnits hat expectException
(die verwendet setExpectedException
in PHPUnit 5.1 und älter sein), dann das Herstellungsverfahren nennt, und schließlich wird die Anrufe vom Spion protokollieren, um die richtigen zu bestätigen, wo sie gemacht wurden.
public function testWhenGetDonationByIdThrowException_itIsLoggedAndThrown() {
$logger = new LoggerSpy();
$loggingRepo = new LoggingDonationRepository(
$this->newThrowingRepository(),
$logger
);
$this->expectException(GetDonationException::class);
$loggingRepo->getDonationById(1337);
$this->assertEquals(
[
[
LogLevel::CRITICAL,
self::GET_DONATION_BY_ID_EXCEPTION_MESSAGE,
$this->newGetDonationException()
]
],
$logger->getLogCalls()
);
}
Das Problem ist, dass, wenn die Ausnahme ausgelöst wird, PHPUnit es auffängt und auswertet expectException
, wonach Ausführung meines Testverfahren nicht fortgesetzt. Die Behauptungen, die meinen Spion verwenden, laufen also niemals.
Ich suche nach einer Möglichkeit, dies zu lösen. Ich habe darüber nachgedacht, die Methode in eine zu teilen, die den expectException
Teil hat, und eine andere, die sowohl einen Dummy Try-Catch für den Produktionscode-Aufruf als auch die Behauptungen für den Spion hat. Irgendwelche Vorschläge für bessere Ansätze?