Testing code that generates warnings

Nov 21, 2019·
Gert de Pagter
Gert de Pagter
· 1 min read

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.