4

I have a class that issues a non-fatal notice:

class MyClass {
    public function foo(){
        trigger_error('Notice this message.', E_USER_NOTICE);
        return true;
    }
}

Here's a basic unit test:

class MyClassTest extends PHPUnit_Framework_TestCase {
    public function testCanFoo(){
        $obj = new MyClass;
        $this->assertTrue($obj->foo());
    }
}

Naturally PHPUnit converts this notice into an exception, which uncaught necessarily fails the test as an error.

There was 1 error:

1) MyClassTest::testCanFoo
Notice this message.

Firstly, let me point out that I love that I can read this notice, and this is what I want, but without failing the test.

I know I can get the test to pass with a docblock.

class MyClassTest extends PHPUnit_Framework_TestCase {
    /**
     *  @expectedException PHPUnit_Framework_Error_Notice
     */
    public function testCanFoo(){
        $obj = new MyClass;
        $this->assertTrue($obj->foo());
    }
}

But now the notice is completely swallowed up.

PHPUnit 5.5.4 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 17 ms, Memory: 4.00MB

OK (1 test, 1 assertion)

How can I get it to both pass the test and view the notice message?

Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
  • [This question](http://stackoverflow.com/questions/8412746/ignoring-the-php-warnings-in-phpunit) looks like it has some useful info on this. – Don't Panic Sep 16 '16 at 16:46
  • Thanks @Don'tPanic I did actually come across that question, but both are suppression alternatives to my docblock solution. – Jeff Puckett Sep 16 '16 at 16:48
  • Ah, I see. I wasn't sure if not converting them to exceptions would prevent them from displaying or not. – Don't Panic Sep 16 '16 at 16:49
  • @Don'tPanic actually, that answer is what I needed after all, thank you. I'm not sure how I missed it on the first pass. – Jeff Puckett Sep 16 '16 at 18:31

2 Answers2

2

You can disable the conversion into exception in this manner:

class MyClassTest extends PHPUnit_Framework_TestCase {
    public function testCanFoo(){
        // disable conversion into exception
        PHPUnit_Framework_Error_Notice::$enabled = false;
        $obj = new MyClass;
        $this->assertTrue($obj->foo());
    }
}
Matteo
  • 37,680
  • 11
  • 100
  • 115
0

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

You can test both for the correct Waring/Notice type as well as the error message:

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 notice string');
    }
}

Cheers.

Jacco
  • 23,534
  • 17
  • 88
  • 105