В моем проекте 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: 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 в конструктор моего тестового примера?
@Cerad Я не хочу тестировать Swift_Mailer, но я действительно хочу отправлять почту во время теста с помощью Swift_Mailer.





Тесты не являются частью контейнера и не действуют как службы, поэтому ваше решение недействительно. Расширьте Symfony\Bundle\FrameworkBundle\Test\KernelTestCase и сделайте это вместо этого (сначала убедитесь, что ваша служба общедоступна):
protected function setUp()
{
static::bootKernel();
$this->mailer = static::$kernel->getContainer()->get('mailer');
}
protected function tearDown()
{
$this->mailer = null
}
В этом случае вы должны определить службу или ее псевдоним как общедоступную.
Нет в Symfony 4
Почему нет? Это не работает в Symfony 4.2 без определения псевдонима
Очень хорошо объяснено здесь symfony.com/blog/new-in-symfony-4-1-simpler-service-testing
Мокинг службы не работает без определения службы или ее псевдонима как общедоступной.
Принятый ответ не будет работать для служб, которые не определены как общедоступные. Однако после Symfony 4.1, чтобы иметь доступ к частным сервисам во время тестирования, вам необходимо получить сервис из специального контейнера для тестирования.
Из документации Symfony:
tests based on
WebTestCaseandKernelTestCasenow access to a special container via thestatic::$containerproperty 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
);
}
}
В документации довольно ясно, что в базовом тестовом примере ничего не известно о контейнере Symfony. И, конечно же, оператор php new игнорирует контейнер. Что еще более важно, спросите себя, почему вы чувствуете необходимость тестировать класс Swift_Mailer? Для этого уже есть несколько тестов. Вы можете посмеяться над этим.