Jayy
Jayy

Reputation: 14728

PHPUnit: assert E_USER_WARNING is generated as expected without ending a test

I want to test code to show that it produces an E_USER_WARNING in certain circumstances.

I found this article which addresses the problem, so as I see it I have these options:

  1. Copying that code into every TestSuite which needs to test for warnings
  2. Making a subclass of PHPUnit's TestCase that has that code, and have my tests inherit from that
  3. Use composition, i.e. make a helper class that achieves the same.

I don't like 1, for obvious reasons - I can't imagine the author had that option in mind.

I don't like 2, because there are some tests that I might use a third party TestCase that already extends PHPUnit's TestCase, so it would get complicated or messy if I wanted to add that functionality for that subclass as well by subclassing that subclass.

Option 3 sounds the best. But...

This all seems to be reinventing the wheel. Aren't there any off-the-shelf solutions for PHPUnit to assert a warning has been generated as expected? If not, is there a good pattern for this that anyone could share?

For better or worse, I very strongly want to stick with PHPUnit for reasons such as:

Upvotes: 2

Views: 730

Answers (2)

Jacco
Jacco

Reputation: 23749

While this does not solve your problem, we went with option 2: write a BaseTestCase that adds functionality to the PHPUnit's PHPUnit\Framework\TestCase.

It has been published under the MIT license as Netsilik/BaseTestCase and can be installed using composer:

composer require netsilik/base-test-case


Testing for E_WARNING, E_NOTICE, E_USER_WARNING, etc. is now rather simple

<?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_whenWarningTriggered_weCanTestForIt()
    {
        $foo = new Foo();
        $foo->bar();

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


We also tried to achieve the same using Traits, but the resulting solution was far from elegant.

Upvotes: 0

jeromegamez
jeromegamez

Reputation: 3541

You can configure PHPUnit to convert notices, warnings and errors to exception by modifying your phpunit.xml file, see https://phpunit.de/manual/current/en/appendixes.configuration.html .

For instance, if you set convertWarningsToExceptions to true, you can catch the warning by setting the expected exception to \PHPUnit_Framework_Error_Warning, like this:

/**
 * @expectedException \PHPUnit_Framework_Error_Warning
 */
public function testFoo()
{
    // ...
}

Upvotes: 3

Related Questions