Search code examples
unit-testingsymfonyphpunitswiftmailersymfony4

Symfony 4.1: How to use Dependency Injection in UnitTest (Swift_Mailer)


In my Symfony4.1-project i am trying to test a method, which should send mails using SwiftMailer, via a unit test.

My test class looks like this

namespace App\Tests;

use App\Controller\UserImageValidationController;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;

class UserImageValidationControllerTest extends TestCase
{

    private $mailer = null;
    public function __construct(\Swift_Mailer $testmySwiftMailer)
    {
        $this->mailer = $testmySwiftMailer;
    }

    public function testMail()
    {
        $controller = new UserImageValidationController();

        $controller->notifyOfMissingImage(
            'a',
            'b',
            'c',
            'd',
            $this->mailer
        );
    }
}

The problem is, that when i run ./bin/phpunit i get an exception saying

Uncaught ArgumentCountError: Too few arguments to function App\Tests\UserImageValidationControllerTest::__construct(), 0 [...] and exactly 1 expected [...]

It seemes like in the test environment DI isn't working.

So i added

bind:
    $testmySwiftMailer: '@swiftmailer.mailer.default'

To my config/services_test.yaml but i still got the same error. I also added autowiring: true to that file (just to try it) and it also doesn't work. Also, i tried with a service-alias, like it states in the file's comments: still no success.

How do i get the swiftmailer injected into my test case constructor?


Solution

  • Tests are not part of the container and don't act as services so your solution is not valid. Extend Symfony\Bundle\FrameworkBundle\Test\KernelTestCase and do that instead (making sure your service is public first):

    protected function setUp()
    {
        static::bootKernel();
    
        $this->mailer = static::$kernel->getContainer()->get('mailer');
    }
    
    protected function tearDown()
    {
        $this->mailer = null;
    }