Calamity Jane
Calamity Jane

Reputation: 2666

proper way to test a service in Symfony 4, with database access

What would be the proper way to test a service in Symfony 4, which also accesses the database?

I am new in Symfony4 (before I developed for Symfony2) and I want to write my first test for a Service.

This service is writing via Entities / Doctrine / ORM in the database and each of my methods, I want to test is triggering a database save.

In Symfony 2 this was the case when I used rather KernelTestCase instead of the PHPUnit_Framework_TestCase because mocking the EntityManager was a pain in the ass and often I also wanted to check the result in the test db.

All examples for Symfony 4 only mention the KernelTestCase for testing Commands.

My class:

class UserPropertyService implements UserPropertyServiceInterface
{


    public function __construct(EntityManager $em, LoggerInterface $logger)
    {
    ....
    }

....
}

My attempt at a Test:

class UserPropertyServiceTest extends KernelTestCase
{
    /** @var UserPropertyService */
    private $userPropertyService;

    public function setUp()
    {
        self::bootKernel();
        $client = static::createClient();
        $container = $client->getContainer();

        $this->userPropertyService = self::$container->get('app.user_management.user_property_service');
}

results in:

Cannot autowire service "App\Service\UserManagement\UserPropertyService": argument 
"$em" of method "__construct()" references class "Doctrine\ORM\EntityManager" 
but no such service exists. 
Try changing the  type-hint to one of its parents: interface "Doctrine\ORM\EntityManagerInterface", 
or interface "Doctrine\Common\Persistence\ObjectManager".

What is the proper approach here? Which test class should I use?

Upvotes: 1

Views: 2090

Answers (1)

D. Schreier
D. Schreier

Reputation: 1788

This is how look like a service test (do not get your Container through the client, those containers are different)

By the way, you can't use static::createClient(); if you extend from KernelTestCase (misunderstanding with controller test and the WebTestCase class ?)

<?php

namespace App\Tests\Service;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class UserPropertyServiceTest extends KernelTestCase
{
    /** @var UserPropertyService */
    private $myService;

    public function setUp() {
        self::bootKernel();
        $this->myService = self::$kernel->getContainer()->get('app.user_management.user_property_service');
    }

}

Upvotes: 1

Related Questions