Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute code after trigger_error(..., E_USER_WARNING) in unit test (PHPUnit)?

I have code like this:

class ToBeTested
{
  function simpleMethod($param)
  {
    if(0 === $param)
    {
      trigger_error("Param is 0!", E_USER_WARNING);
      return false;
    }

    return true;
  }
}

and test for this code:

class SimpleTest extends PHPUnit_Framework_TestCase
{
   function testSimpleMethod()
   {
     $toBeTestedObject = new ToBeTested();
     $this->assertFalse($toBeTestedObject->simpleMethod(0));
   }
}

I know how to test, if the error is triggered ($this->setExpectedException()), but I don't know how to execute the code after trigger_error() function.

Remember that in PHPUnit E_USER_WARNING is not converted into PHPUnit_Framework_Error_Warning (which can be disabled), but it is converted into PHPUnit_Framework_Error (which can't be disabled).

like image 821
tonygreen Avatar asked Dec 05 '22 01:12

tonygreen


2 Answers

This is one of those places where you are 'officially' allowed to use the @ operator :)

Make one test to check the return value, another test to check if the warning gets triggered. And by the way, I'd suggest you do test if the warning is triggered.

class SimpleTest extends PHPUnit_Framework_TestCase
{
   function testSimpleMethodReturnValue()
   {
     $toBeTestedObject = new ToBeTested();
     $this->assertFalse(@$toBeTestedObject->simpleMethod(0));
   }

   /**
    * @expectedException PHPUnit_Framework_Error
    */
   function testSimpleMethodEmitsWarning() {
     $toBeTestedObject = new ToBeTested();
     $toBeTestedObject->simpleMethod(0);
   }
}
like image 162
edorian Avatar answered Dec 11 '22 09:12

edorian


What you should be using is set_error_handler() (link) and restore_error_handler() which lets you set a function to deal with errors of a given type. It also has the added bonus of giving you a place to test the warning at the same time.

So, something like this:

class SimpleTest extends PHPUnit_Framework_TestCase
{
   function testSimpleMethod()
   {
     set_error_handler(array($this, '_handleWarnedMethod'), E_USER_WARNING);

     $toBeTestedObject = new ToBeTested();
     $this->assertFalse($toBeTestedObject->simpleMethod(0));

     restore_error_handler();
   }

   private function _handleWarnedMethod($errno, $errstr)
   {
      $this->assertEquals(E_USER_WARNING, $errno);
      $this->assertEquals('Param is 0!', $errstr);
   }

}

As always, error suppression isn't the best idea :)

like image 29
pivotal Avatar answered Dec 11 '22 10:12

pivotal