phpsymfonyphpunitphp-7.2symfony-flex

symfony simple-phpunit error 'You have requested a non-existent service "test.client"' only in deployment script


PHP: 7.2.7

SYMFONY: 3.4.12

PHPUNIT-BRIDGE: 4.1.1 (phpunit 6.5.8)


I have a deployment script written in PHP that runs as the root user and, since upgrading to php 7.2 from 7.0 and updating my code accordingly, it has begun failing inexplicably when running the phpunit tests. I'm sure I am at fault here, but I have gotten nowhere after many hours of debugging and hope someone might be able to point me in the right direction.

The script runs as root, and when it executes the following:

exec("runuser MY-USER -c 'bin/simple-phpunit'", $output, $returnCode);

All of my tests fail with:

You have requested a non-existent service "test.client"

There are lots of SO issues about this error, and it related to the phpunit environment not being set to "test". My phpunit.xml uses the proper value:

<env name="APP_ENV" value="test" />

The crazy part is that the unit tests run just fine when I run them myself (as MY-USER). They even run properly when I log in as root and execute

runuser MY-USER -c 'bin/simple-phpunit'

They even run when I do

$ sudo su
$ php -a
php > exec("runuser MY-USER -c 'bin/simple-phpunit'", $output, $returnCode);

And when I got desperate and started dumping variables to the console, it seems that everything is proper:

echo "ENV = " .getenv('APP_ENV');  // [OUTPUT BELOW]

ENV = dev

exec('bin/console debug:container test.client -e test', $output, $return);
var_dump(implode("\n", $output));  // [OUTPUT BELOW]

Information for Service "test.client"
=====================================

---------------- ---------------------------------------
Option           Value
---------------- ---------------------------------------
Service ID       test.client
Class            Symfony\Bundle\FrameworkBundle\Client
Tags             -
Public           yes
Synthetic        no
Lazy             no
Shared           no
Abstract         no
Autowired        no
Autoconfigured   no

exec("runuser arderyp -c 'bin/simple-phpunit --debug'", $output, $return);
var_dump(implode("\n", $output));  // [OUTPUT BELOW]

# Everything fails in the same fashion as below
8) App\Tests\Authentication\Security\SomeTest::testSomething
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "test.client".

Before running the tests I properly parse my .env using the symfony standard approach:

$dotenv = new Dotenv();
$dotenv->load('.env');

Solution

  • Well, it looks like I too was bit by this change in PHPUnit: https://github.com/sebastianbergmann/phpunit/issues/2353

    Adding the force="true" attribute to all of my env elements resolved the issue.

    The problem here is that I am loading (via Dotenv) my local .env file before getting to this phpunit step. Without the force attribute mentioned above, the environment variables in phpunit.xml are not overriding those already set by .env. Consequently, the tests are run with APP_ENV=dev instead of APP_ENV=test, which causes the test.client service to not be recognized, because its only accessible in the test environment. Apparently this is new phpunit functionality. Earlier versions of phpunit would allow the variable overriding by default, which explains why I only started experiencing this issue after upgrading PHP (and with it, phpunit).