Symfony 4.2 How to do a service public only for tests

依然范特西╮ 提交于 2019-12-24 19:29:45

问题


I have the solution to make the service public. In the services.yml

    test_phpdocxService:
          alias: App\Service\PhpDocxService
          public: true

I try to access the service:

$container = self::$container;
$phpDocxService = $container->get('test_phpdocxService');

$this->filename = $phpDocxService->generateDocxDocument('docx/aaa.html.twig', $data);

But I find it not so nice. Is there an another way to do that?


回答1:


You need to create in config/config_test.yml and declare that service is public and other configuration for tests there .

This approach you can use in symfony 3/4.

You can read tutorial here: https://symfonycasts.com/screencast/phpunit/integration-tests

About Symfony simple testing 4.1 feature please read @Cerad post




回答2:


Okay. So there is an issue about testing private services that are not used anywhere in your app. It is still open and being discussed but basically, for now, you need to typehint against your private service somewhere in your app before you can access it in a test.

Using a fresh 4.4.2 install:

# src/Service/PhpDocxService.php
namespace App\Service;
class PhpDocxService
{
    public function sayHello()
    {
        return 'hello';
    }
}

# src/Controller/MyController.php
namespace App\Controller;

use App\Service\PhpDocxService;


class MyController
{
    #****** This is the secret ******
    public function __construct(PhpDocxService $phpDocxService)
    {

    }
}

# src/tests/MyTest.php
namespace App\Tests;

use App\Service\PhpDocxService;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class MyTest extends WebTestCase
{
    public function testServiceFound()
    {
        self::bootKernel();

        // gets the special container that allows fetching private services
        $container = self::$container;

        $phpDocxService = $container->get(PhpDocxService::class);

        $this->assertEquals('hello',$phpDocxService->sayHello());
    }
}

Typehint your service in a controller's constructor and everything works as expected.




回答3:


The autowiring exists Since Symfony 3.4 but with the 4.x version, it is activated by default.

So, all your class inside /src directory is public and setted as services.

Go to /config/services.yaml, you'll find this code:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'

This means that your /src/Services/PhpDocxService.php file is callable by App/Services/PhpDocxService

The solution what you found is to call your service by $this->getContainer()->get('test_phpdocxService');




回答4:


YOU DON'T! :)

Instead, you use the new Simpler service testing, implemented in Symfony 4.1.

With that, tests based on WebTestCase and KernelTestCase now access to a special container via the static::$container property that allows fetching non-removed private services.

And that means that private services are automatically public in tests if you use that container.

Just do something like:

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class SomeClassToTest extends WebTestCase
{
    public function getService(string $service)
    {
        self::bootKernel();
        $container = self::$kernel->getContainer();
        $container = self::$container;

        return self::$container->get($service);
    }

    public function tesSomething()
    {
        $imageProcessor = $this->getService('app.some.service');
    }

And now you can get the private 'app.some.service' service in testing environments.



来源:https://stackoverflow.com/questions/54466158/symfony-4-2-how-to-do-a-service-public-only-for-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!