Custom service not found by unit test of shopware 6 plugin

Viewed 418

I wrote a plugin in which I want to create tests now. I followed the official documentation and changed my phpunit.xml.dist accordingly to my dev environment.

The tests are running but the container doesn't know my custom definitions/repositories. Did I set up something wrong?

I tried to run it on a standard Dockware Container.

phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/7.1/phpunit.xsd"
         colors="true"
         bootstrap="../../../vendor/shopware/core/TestBootstrap.php"
         cacheResult="false">

    <php>
        <ini name="error_reporting" value="-1"/>
        <server name="KERNEL_CLASS" value="Shopware\Production\Kernel"/>
        <env name="APP_ENV" value="test"/>
        <env name="APP_DEBUG" value="1"/>
        <env name="APP_SECRET" value="*"/>
        <env name="SHELL_VERBOSITY" value="-1"/>
    </php>

    <testsuites>
        <testsuite name="base">
            <directory>src/Test</directory>
        </testsuite>
        <testsuite name="employee">
            <directory>src/Components/Employee/Test</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory suffix=".php">./</directory>
        </whitelist>
    </filter>
</phpunit>

The error:

$ bash ./bin/phpunit.sh 
PHPUnit 9.5.9 by Sebastian Bergmann and contributors.

Warning:       Your XML configuration validates against a deprecated schema.
Suggestion:    Migrate your XML configuration using "--migrate-configuration"!

E.                                                                  2 / 2 (100%)

Time: 00:00.029, Memory: 40.50 MB

There was 1 error:

1) ***\EmployeeRouteTest::testEmployeeIsCreatedCorrectly
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "***_employee.repository". Did you mean one of these: "app_template.repository", "mail_template.repository", "media_folder.repository"?

/var/www/html/vendor/symfony/dependency-injection/Container.php:271
/var/www/html/vendor/symfony/dependency-injection/Container.php:219
/var/www/html/vendor/symfony/framework-bundle/Test/TestContainer.php:111
/var/www/html/custom/plugins/***/src/Components/Employee/Test/EmployeeRouteTest.php:30

ERRORS!
Tests: 2, Assertions: 5, Errors: 1.
1 Answers

You have to ensure that your plugin is installed and activated in the DB the tests are executed against.

You can either do it by executing the plugin:install command in your custom phpunit script, or install the plugin in your TestBootstrap file.

Depends a little bit on your unit test setup and especially the database setup during the test execution.

By default the shopware unit tests are executed against a special {db-name}_test database, so it may happen that your plugin is installed and active in your default database, but the unit tests run with a different database.

If you use the shopware db way there is the ./psh.phar init-test-databases command that will copy the content from the default database to the test database. If you have a custom setup command that automatically installs your plugin make sure to call the init-test-databases command, too, so your plugin is also marked as installed and activated in the test database.

Edit

Since writing the original answer we added a helper to make it easier to bootstrap the application for testing purposes.

We introduced a TestBootstrapper that can be configured to bootstrap the application in the way you want.

The easiest way to do it, is to create a TestBootstrap.php file with the following content:

require PATH_TO_SHOPWARE_CORE . '/TestBootstrapper.php';

(new TestBootstrapper())
    ->bootstrap();

And use that file as the bootstrap file for phpunit.

If you want to ensure that your plugin is installed during the tests you can configure that:

require PATH_TO_SHOPWARE_CORE . '/TestBootstrapper.php';

(new TestBootstrapper())
    ->addActivePlugins('YourPluginName')
    ->bootstrap();

For a real life example on how the TestBootstrapper is used you may take a look at the PayPal plugin.

Related