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

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

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

我的测试class看起来像这样

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: Too few arguments to function App\Tests\UserImageValidationControllerTest::__construct(), 0 [...] and exactly 1 expected [...]

在测试环境中似乎DI没有工作。

所以我添加了

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

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

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

测试不是容器的一部分,也不充当服务,因此您的解决方案无效。扩展 Symfony\Bundle\FrameworkBundle\Test\KernelTestCase 并改为这样做(确保您的服务首先是 public):

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

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

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

已接受的答案不适用于未定义为 public 的服务。但是在Symfony 4.1之后,为了能够在测试时访问私有服务,你需要从一个特殊的测试容器中获取服务。

来自 Symfony 文档:

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

示例:

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