我使用Twig_Environment来呈现要发送的html邮件.我有一个NotificationService类,其他服务使用它来发送这些邮件.
在正常使用中,一切正常,但由于更新到2.8,因此单元测试失败:
Symfony\Component\DependencyInjection\Exception\RuntimeException: You have requested a synthetic service ("kernel"). The DIC does not know how to construct this service
我调试了StackTrace,问题似乎是Twig_Environment(使用file_locator
哪个注入kernel
)
/** * Notification Service Class * * @DI\Service("app.service.notification") */ class NotificationService extends Generic { /** * @var \Twig_Environment */ protected $twig; /** * @var \Swift_Mailer */ protected $swiftMailer; /** * @var string */ protected $mailTemplate = 'VendorAdminBundle:Email:system2.html.twig'; /** * @param \Swift_Mailer $swiftMailer * @param \Twig_Environment $twig * * @DI\InjectParams({ * "swiftMailer" = @DI\Inject("mailer"), * "twig" = @DI\Inject("twig") * }) */ public function __construct(\Swift_Mailer $swiftMailer, \Twig_Environment $twig) { $this->twig = $twig; $this->swiftMailer = $swiftMailer; } /** * Send notification mail to Manager * @param UserEntity $manager * @param array $contacts */ public function notifyManager(UserEntity $manager, array $contacts) { $subject = 'Lorem Ipsum'; $templateFile = "AppBundle:Email:notifyManager.html.twig"; $templateContent = $this->twig->loadTemplate($templateFile); $body = $templateContent->render(array( 'user' => $manager, 'contacts' => $contacts, 'subject' => $subject, )); $this->sendMail($body, $subject, $manager); } }
关于如何解决这个问题的任何指针?
编辑:(根据要求)
class NotificationTest extends DoctrineTestCase { /** * @var \App\Service\Notification */ protected $service; public function setUp() { $this->markTestSkipped('Problem with twig env'); $this->loadFixturesFromDirectory(__DIR__ . '/DataFixtures'); $this->loginUser('admin', $this->getUser(1)); $this->service = $this->container->get('neos.service.notification'); // <-- exception thrown here } [test methods] }
EDIT2:
/** * Class DoctrineTestCase. * * This is the base class to load doctrine fixtures using the symfony configuration */ class DoctrineTestCase extends TestCase { /** * @var \Symfony\Component\DependencyInjection\Container */ protected $container; /** * @var \Doctrine\ORM\EntityManager */ protected $em; /** * @var string */ protected $environment = 'test'; /** * @var bool */ protected $debug = true; /** * @var string */ protected $entityManagerServiceId = 'doctrine.orm.entity_manager'; /** * Constructor. * * @param string|null $name Test name * @param array $data Test data * @param string $dataName Data name */ public function __construct($name = null, array $data = array(), $dataName = '') { parent::__construct($name, $data, $dataName); if (!static::$kernel) { static::$kernel = self::createKernel(array( 'environment' => $this->environment, 'debug' => $this->debug, )); static::$kernel->boot(); static::$kernel->getContainer()->set('kernel', static::$kernel); //<--- Added - but doesnt help } $this->container = static::$kernel->getContainer(); $this->em = $this->getEntityManager(); } /** * Executes fixtures. * * @param \Doctrine\Common\DataFixtures\Loader $loader */ protected function executeFixtures(Loader $loader) { $purger = new ORMPurger(); $executor = new ORMExecutor($this->em, $purger); $executor->execute($loader->getFixtures()); } /** * Load and execute fixtures from a directory. * * @param string $directory */ protected function loadFixturesFromDirectory($directory) { $loader = new ContainerAwareLoader($this->container); $loader->loadFromDirectory($directory); $this->executeFixtures($loader); } /** * Returns the doctrine orm entity manager. * * @return object */ protected function getEntityManager() { return $this->container->get($this->entityManagerServiceId); } }
编辑3:获取内核似乎有时在过去发生了变化.请参阅http://symfony.com/doc/master/cookbook/testing/doctrine.html
我改变了我的构造函数:
public function __construct($name = null, array $data = array(), $dataName = '') { parent::__construct($name, $data, $dataName); if (!static::$kernel) { static::$kernel = self::createKernel(array( 'environment' => $this->environment, 'debug' => $this->debug, )); static::$kernel->boot(); static::$kernel->getContainer()->set('kernel', static::$kernel); //<--- Added - but doesnt help } $this->container = static::$kernel->getContainer(); $this->em = $this->getEntityManager(); }
至:
public function __construct($name = null, array $data = [], $dataName = '') { parent::__construct($name, $data, $dataName); self::bootKernel(); $this->container = static::$kernel->getContainer(); $this->em = $this->getEntityManager(); }
但不幸的是,当测试使用Twig_Env时,它没有修复RuntimeException.
您不应该在测试用例的构造函数中引导内核.这样,它将在第一次测试执行后关闭(参见https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php#L186-L189).您应该在测试用例的setUp()
方法中启动内核.