symfony: KernelTestCase no longer works with PhpUnit 6.0+

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.2.2

Preconditions:

  • Have a blank Symfony project version 3.2.x as installed by Symfony project generator.
  • Install PhpUnit 6.0.x with composer using composer require --dev phpunit/phpunit=~6.0.

Steps to reproduce:

  1. Run PhpUnit 6 with vendor/bin/phpunit -c .

Actual result:

PHP Fatal error:  Class 'PHPUnit_Framework_TestCase' not found in /home/user/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php on line 23

Expected result:

PHPUnit 6.0.3 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 107 ms, Memory: 12.00MB

OK (1 test, 2 assertions)

Notes:

  • It appears the old class name PHPUnit_Framework_TestCase which is used as a parent class of vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php was completely dropped in favor of PSR compatible namespacing in PhpUnit 6 (see this commit).
  • The new namespaced class name was introduced in PhpUnit ~4.8~ 5.4 (see changelog).
  • Would it be possible to replace the parent class of KernelTestCase with the new namespaced class?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 24
  • Comments: 50 (32 by maintainers)

Commits related to this issue

Most upvoted comments

On my current project I’ve put the following in my PHPUnit bootstrap file after the autoloader until it’s resolved on the Symfony and/or PHPUnit levels, with "phpunit/phpunit:"^5.7 || ^6.0" in the composer.json:

// Polyfill PHPUnit 6.0 both ways
if (!class_exists('\PHPUnit\Framework\TestCase', true)) {
    class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
} elseif (!class_exists('\PHPUnit_Framework_TestCase', true)) {
    class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
}

I’m only using this because I want the bundle to support only PHPUnit 6 eventually. In regular projects I’m sticking with 5.x for the time being as @xabbuh suggests.

I’m not sure if this should be a new issue, but the issue also occurs with Symfony 2.8.

Those are needed for the PHPUnit bridge, in fact

You need dev-master of the bridge.

@xabbuh that’s what I did. The workaround above by @curry684 works, so long you don’t use for example LIIP functional test bundle (which I do). I fixed my composer.json (had phpunit using @stable ) and now tests work.

Come to think of it, that polyfill would horribly break many projects. A regular polyfill adds missing functionality without breaking anything, but in this case many projects might consciously stay on 5.x for some time and thus would explicitly break on the suggested solution, or get stuck with an old Symfony version.

I think the only really transparent solution is changing KernelTestCase.php to something like this:

namespace Symfony\Bundle\FrameworkBundle\Test;

use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\KernelInterface;

// Alias the PHPUnit 6.0 ancestor if available, else fall back to legacy ancestor
if (class_exists('\PHPUnit\Framework\TestCase', true)) {
  class KernelTestCaseAncestor extends \PHPUnit\Framework\TestCase {}
} else {
  class KernelTestCaseAncestor extends \PHPUnit_Framework_TestCase {}
}

/**
 * KernelTestCase is the base class for tests needing a Kernel.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class KernelTestCase extends KernelTestCaseAncestor
{
  ...
}

Just tried it out and this makes my local tests pass both on 5.7 and 6.0.

Then again, perhaps it would be easier on Symfony and other frameworks if @sebastianbergmann either added this alias to 6.0 until 6.1 comes out, and marks 6.1 as conflicting with symfony/framework-bundle:<=3.2.2, or add that conflicts rule to the next 6.0.x patch - that would perhaps be a lot cleaner.