[ACCEPTED]-How to catch PHP Warning in PHPUnit-phpunit

Accepted answer
Score: 40

PHPUnit_Util_ErrorHandler::handleError() throws one of several exception types based 2 on the error code:

  • PHPUnit_Framework_Error_Notice for E_NOTICE, E_USER_NOTICE, and E_STRICT
  • PHPUnit_Framework_Error_Warning for E_WARNING and E_USER_WARNING
  • PHPUnit_Framework_Error for all others

You can catch and expect 1 these as you would any other exception.

/**
 * @expectedException PHPUnit_Framework_Error_Warning
 */
function testNegativeNumberTriggersWarning() {
    $fixture = new someClass;
    $fixture->loadValue(-1);
}
Score: 12

I would create a separate case to test when 2 the notice/warning is expected.

For PHPUnit 1 v6.0+ this is the up to date syntax:

use PHPUnit\Framework\Error\Notice;
use PHPUnit\Framework\Error\Warning;
use PHPUnit\Framework\TestCase;

class YourShinyNoticeTest extends TestCase
{

    public function test_it_emits_a_warning()
    {
        $this->expectException(Warning::class);

        file_get_contents('/nonexistent_file'); // This will emit a PHP Warning, so test passes
    }


    public function test_it_emits_a_notice()
    {
        $this->expectException(Notice::class);

        $now = new \DateTime();
        $now->whatever; // Notice gets emitted here, so the test will pass
    }
}
Score: 10

What worked for me was modifying my phpunit.xml 2 to have

<phpunit
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         strict="true"
         >
</phpunit>

The key was to use strict="true" to get the warnings 1 to result in a failed test.

Score: 3

You can also write a phpunit.xml file (on 1 your tests dir) with this:

<phpunit 
convertErrorsToExceptions="true" 
convertNoticesToExceptions="false" 
stopOnFailure="false">
</phpunit>
Score: 1

Using Netsilik/BaseTestCase (MIT License) you can test directly 3 for triggered Errors/Warnings, without converting 2 them to Exceptions:

composer require netsilik/base-test-case


Testing for an E_USER_NOTICE:

<?php
namespace Tests;

class MyTestCase extends \Netsilik\Testing\BaseTestCase
{
    /**
     * {@inheritDoc}
     */
    public function __construct($name = null, array $data = [], $dataName = '')
    {
        parent::__construct($name, $data, $dataName);

        $this->_convertNoticesToExceptions  = false;
        $this->_convertWarningsToExceptions = false;
        $this->_convertErrorsToExceptions   = true;
    }

    public function test_whenNoticeTriggered_weCanTestForIt()
    {
        $foo = new Foo();
        $foo->bar();

        self::assertErrorTriggered(E_USER_NOTICE, 'The warning string');
    }
}

Hope 1 this helps someone in the future.

Score: 0
public function testFooBar(): void
{
    // this is required
    $this->expectWarning();
    // these are optional
    $this->expectWarningMessage('fopen(/tmp/non-existent): Failed to open stream: No such file or directory');
    $this->expectWarningMessageMatches('/No such file or directory/');

    fopen('/tmp/non-existent', 'rb');
}

0

More Related questions