Symfony 4.1:如何在UnitTest中使用依赖注入(Swift_Mailer)

时间:2018-06-14 13:04:59

标签: unit-testing symfony phpunit swiftmailer symfony4

在我的Symfony4.1项目中,我试图测试一个方法,该方法应该通过单元测试使用SwiftMailer发送邮件。

我的测试类看起来像这样

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
        );
    }
}

问题是,当我运行./bin/phpunit时,我得到一个例外

  

Uncaught ArgumentCountError:函数App \ Tests \ UserImageValidationControllerTest :: __ construct(),0 [...]和1个预期[...]

的参数太少

在测试环境中,DI似乎无法正常工作。

所以我添加了

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

到我的 config / services_test.yaml ,但我仍然遇到同样的错误。 我还在该文件中添加了autowiring: true(只是为了尝试它)而且它也不起作用。 此外,我尝试使用服务别名,就像它在文件的评论中所述:仍然没有成功。

如何将swiftmailer注入我的测试用例构造函数?

2 个答案:

答案 0 :(得分:1)

测试不是容器的一部分,也不作为服务,因此您的解决方案无效。扩展Symfony \ Bundle \ FrameworkBundle \ Test \ KernelTestCase并改为:

protected function setUp()
{
    static::bootKernel();

    $this->mailer = static::$kernel->getContainer()->get('mailer');
}

protected function tearDown()
{
    $this->mailer = null
}

答案 1 :(得分:0)

接受的答案不适用于未定义为公共的服务。但是,在syfmony 4.1之后,要能够在测试时访问私有服务,您需要从特殊的测试容器中获取服务。

来自symfony文档:

基于WebTestCaseKernelTestCase的测试现在可以通过static::$container属性访问一个特殊的容器,该属性允许获取未删除的私有服务

示例:

namespace App\Tests;

use App\Controller\UserImageValidationController;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class UserImageValidationControllerTest extends WebTestCase
{
    private $mailer = null;

    protected function setUp()
    {
        self::bootKernel();

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

        $this->mailer = $container->get('mailer');
    }

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

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