An elegant way to test Services / Service containers in Symfony3 using PHPUnit

Recently, I am exploring the structure of Symfony 3 and Injection Dependency .

I want you to help me resolve my doubts about the Services testing method in Symfony 3 using PHPUnit . I have some problems how to do it right.

Let's make an example of the Service class:

// src/AppBundle/Services/MathService.php namespace AppBundle\Services; class MathService { public function subtract($a, $b) { return $a - $b; } } 

I see that typically UnitTest classes in Symfony test Controllers .

But what can I test for independent classes, for example Services (for example, with business logic) instead of Controllers ?

I know that there are at least two ways to do this:


1. Create a test class that extends PHPUnit_Framework_TestCase and creates a service object inside some methods . strong> or constructor in this test class (exactly the same as in Symfony's docs about testing )

 // tests/AppBundle/Services/MathTest.php namespace Tests\AppBundle\Services; use AppBundle\Services\MathService; class MathTest extends \PHPUnit_Framework_TestCase { protected $math; public function __construct() { $this->math = new MathService(); } public function testSubtract() { $result = $this->math->subtract(5, 3); $this->assertEquals(2, $result); } } 

2. Make our Service Container service class using dependency injection. Then create a test class that extends KernelTestCase to gain access to the kernel. This will give us the opportunity to enter our service using a container from the kernel (based on Symfony's Doctrine testing documents).

Service Container Configuration:

 # app/config/services.yml services: app.math: class: AppBundle\Services\MathService 

Now our Test Class will look like this:

 // tests/AppBundle/Services/MathTest.php namespace Tests\AppBundle\Services; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; class MathTest extends KernelTestCase { private $math; protected function setUp() { self::bootKernel(); $this->math = static::$kernel ->getContainer() ->get('app.math'); } public function testSubtract() { $result = $this->math->subtract(5, 3); $this->assertEquals(2, $result); } } 

There are advantages when we choose this path.

First, we have access to our Service Container in controllers and tests through Injection Dependency .

Secondly - if in the future we want to change the location of the Service class or change the class name - compared to 1. case - we can avoid changes in many files, because we will change the path / name at least in the services.yml file.


My questions:

Is there another way to test the Service class in Symfony 3? Which method is better and should be used?

+5
source share
1 answer

The easiest way to achieve what you need is to use this package: https://github.com/lastzero/test-tools

This allows you to easily work with Symfony container dependencies without any kernel overhead.

+1
source

Source: https://habr.com/ru/post/1259993/


All Articles