Phpunit: Method PHPUnit_Framework_ExpectationFailedException::__toString() must not throw an exception

Created on 4 Feb 2015  路  12Comments  路  Source: sebastianbergmann/phpunit

Occasionally, when running a test, this error comes up when a test fails:

PHP Fatal error: Method PHPUnit_Framework_ExpectationFailedException::__toString() must not throw an exception in phar:///usr/local/bin/phpunit/phpunit/TextUI/ResultPrinter.php on line 0

Any simple failure can trigger this error. I tried using a try/catch on my autoloader to see if there were any classes from PHPUnit that my autoloader shouldn't be trying to load, as I had a previous problem with my autoloader trying to load the now deprecated PHPUnit_Extensions_Story_TestCase, but did not catch anything. I'm not too entirely sure how to properly replicate this problem as I can't find a pattern to why the error appears. Sometimes I get the correct failed assertion message instead of the error.

Also, sometimes I get this error instead:

PHP Fatal error: PHP Fatal error: Method PHPUnit_Framework_ExceptionWrapper::__toString() must not throw an exception in phar:///tmp/phpunit.phar/phpunit/TextUI/ResultPrinter.php on line 0

which also came up in this previous thread: https://github.com/sebastianbergmann/phpunit/issues/1485. I tried excluding the Symfony class from my autoloader, but it didn't change anything.

Most helpful comment

I'm having the same problem. To fix that i had to change the line 93 of the PHPUnit_Util_Blacklist class:

FROM:

...
if (!class_exists($className)) {
...

TO:

..
if (!class_exists($className, false)) {
..

Why? I dont think you have to call autoload in this case, since this is only checking for the classes loaded which will be filtered.

All 12 comments

Also, I'm using PHPUnit 4.4.5.

Does your autoloader throw an exception when it can't find a class?

Yes, it throws Exception: include_once(nonExistantClass.php): failed to open stream: No such file or directory

Your autoloader must do anything for code that it is not responsible for.

Are you saying that my autoloader is trying to load a class it shouldn't to get the PHPUnit_Framework_ExpectationFailedException error? Is there a way to pinpoint this class? Because when I put my autoloader inside a try/catch, it doesn't catch anything.

I'm having the same problem. To fix that i had to change the line 93 of the PHPUnit_Util_Blacklist class:

FROM:

...
if (!class_exists($className)) {
...

TO:

..
if (!class_exists($className, false)) {
..

Why? I dont think you have to call autoload in this case, since this is only checking for the classes loaded which will be filtered.

Same issue. I think Sebastian meant "Your autoloader must NOT do anything for code that it is not responsible for." E.g. if your code registers an exception handler or shutdown function via set_exception_handler or register_shutdown_function and there's an exception thrown anywhere in there, that can trigger this PHPUnit error.

How come this still isn't fixed after all this time? All that's needed is a simple try-catch in https://github.com/sebastianbergmann/phpunit/blob/master/src/Util/Blacklist.php

Or to disable class auto-loading as cezarpirajant suggests.

In my case, it was the Composer\Autoload\ClassLoader class that was missing and causing the rendering error.

Since I didn't want to patch the PHPUnit library, I ended up doing this inside of my PHPUnit bootstrap instead:

// Remove missing classes from the PHPUnit blacklist, to prevent an exception rendering error.
// Workaround to fix the actual PHPUnit bug (see https://github.com/sebastianbergmann/phpunit/issues/1598).
if (!empty(PHPUnit_Util_Blacklist::$blacklistedClassNames)) {
  foreach (PHPUnit_Util_Blacklist::$blacklistedClassNames as $className => $parent) {
    try {
      if (!class_exists($className)) {
        unset(PHPUnit_Util_Blacklist::$blacklistedClassNames[$className]);
      }
    } catch (Exception $e) {
      unset(PHPUnit_Util_Blacklist::$blacklistedClassNames[$className]);
    }
  }
}

@Malbeth81 What version of PHPUnit are you running? If the fix is really this simple, pull requests for breaking bugs are still accepted for older versions. Is there a self-contained testcase?

I'm using PHPUnit 5.7.26, however as I pointed out, looking at the current master we still see that nothing was changed in that function: https://github.com/sebastianbergmann/phpunit/blob/master/src/Util/Blacklist.php

@Malbeth81 thanks for your reply, but v5 is too far back to receive further updates. There's bugfixes for 6.x, some new features for v7 and a serious refactoring for beyond.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebastianbergmann picture sebastianbergmann  路  4Comments

joubertredrat picture joubertredrat  路  4Comments

ezzatron picture ezzatron  路  3Comments

keradus picture keradus  路  4Comments

keradus picture keradus  路  3Comments