Testing code that generates warnings
Our code base has a lot of code that looks like this:
<?php
try {
$this->doScaryThing();
} catch(Exception $e) {
trigger_error("Downgraded: " . get_class($e) . ":" . $e->getMessage(), E_USER_WARNING);
}
Or sometimes trigger_error
is used as a way to log other thigns. This makes it rather difficult
to test. Thankfully PHPUnit 8.4 has the expectWarning
method, that allows us to check this:
<?php
public function testItTriggersWarning(): void
{
$object = new Danger();
$this->expectWarning();
$object->doWarningThing();
}
This does mean that the execution stops after the warning is triggered, so we can’t assert anything after that. Thankfully we can still do it in a bit of a ‘hackish’ way:
<?php
public function testItHasCorrectValueAfterWarning(): void
{
$object = new Danger()
$ret = @$object->doWarningThing();
$this->assertSame('good_value', $ret);
}
Personally i like to add an @depends
on that second test, so that it requires the test that it triggers
a warning to pass before it is executed. Of course this does mean we need two tests per case, one for the
triggering of the warning/notice, and one where it is silenced so we can check the output. But it allows
us to test the code, and maybe move to a better logging situation in the future.