core: ApiTestCase: assertJsonContains throws ArraySubset class not found error

API Platform version(s) affected: 2.5.9

Description
This issue started after upgrading API Platform core from 2.5.7 to 2.5.9

When making an assertion such as:

        $this->assertJsonContains([
            'content' => '127.0.0.1',
        ]);

The ArraySubset class is not being found:

20) App\Tests\Functional\ZoneTest::testPutMasterIp
Error: Class 'ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Constraint\ArraySubset' not found

/srv/api/vendor/api-platform/core/src/Bridge/Symfony/Bundle/Test/ApiTestAssertionsTrait.php:98
/srv/api/vendor/api-platform/core/src/Bridge/Symfony/Bundle/Test/ApiTestAssertionsTrait.php:57
/srv/api/tests/Functional/ZoneTest.php:126

Looking at ArraySubset, it was changed from a class to an alias which should match to: ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Constraint\ArraySubsetV9 or ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Constraint\ArraySubsetLegacy

Which both appear to be in the project.

How to reproduce
Make a call to $this->assertJsonContains in a class that extends ApiTestCase

Possible Solution
Unknown.

Additional Context
Symfony 4.4. In phpunit.xml.dist we have

        <server name="SYMFONY_PHPUNIT_VERSION" value="8.3" />

I tried 8.4 and got the same error. 8.5 and I ran into more issues.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 16 (6 by maintainers)

Most upvoted comments

I also have the same problem. As mentioned by @massimilianobraglia, It seems to be caused by authoritative class maps in the test environment of the CI. When using this flag locally the tests also fail. The change suggested by @soyuka (thanks 🙏) in https://github.com/api-platform/core/issues/3962#issuecomment-771700251 unfortunately does not solve it.

Sorry @soyuka, I did not manage to try your solution. Instead we found that in dev env we used a wrong composer flag when installing the dependencies:

https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps

Using this only in prod environment fixes the issue for me

@geoff-maddock I just tried another workaround and it seems to work well: in your phpunit bootstrap file just add the following:

use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Constraint\ArraySubset;
use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Constraint\ArraySubsetV9;

// [...]

if (!\class_exists(ArraySubset::class)) {
    class_alias(ArraySubsetV9::class, ArraySubset::class);
}

In this way the ArraySubsetV9 is explicitly loaded once and aliased as ArraySubset

My work around was re-writing the tests I was using to use assertJsonEquals.
Made my tests a bit harder to read/longer, but it was doable.