1

今天,我尝试将我的项目升级到新版本的 Symfony (3.3),但我的模拟遇到了问题。

直到今天,我一直在做这样的模拟:

$client     = $this->makeClient();
$mockObject = new \stdClass();

$mock = $this->getMockBuilder('SomeClass')
            ->disableOriginalConstructor()
            ->setMethods(['method1', 'method2'])
            ->getMock();

$mock->expects($this->once())
    ->method('method1')
    ->will($this->returnValue($mockObject));

$client->getContainer()->set('my_service', $mock);

在这里,method1只是一个 Guzzle 的帖子,没有别的。

现在,我收到以下错误:

设置“my_service”预定义服务自 Symfony 3.3 以来已被弃用,并且在 Symfony 4.0 中不再支持:1x

经过一番研究,我似乎无法使用我的代码的最后一行。问题是,我看不到也找不到解决此弃用的任何解决方案。

4

2 回答 2

2

解决您的问题的方法很少。

TestDoubleBundle

TestDoubleBundle可以更轻松地创建测试替身。您可以使用依赖注入标签自动将服务替换为存根或假服务。

覆盖容器

另一种方法是在测试环境中扩展容器,因此它允许存根。这是这个想法的草稿:

<?php

namespace Zalas\Test\DependencyInjection;

use Symfony\Component\DependencyInjection\Container;

class MockerContainer extends Container
{
    /**
     * @var object[] $stubs
     */
    private $stubs = array();

    public function stub($serviceId, $stub)
    {
        if (!$this->has($serviceId)) {
            throw new \InvalidArgumentException(sprintf('Cannot stub a non-existent service: "%s"', $serviceId));
        }

        $this->stubs[$serviceId] = $stub;
    }

    /**
     * @param string  $id
     * @param integer $invalidBehavior
     *
     * @return object
     */
    public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
    {
        if (array_key_exists($id, $this->stubs)) {
            return $this->stubs[$id];
        }

        return parent::get($id, $invalidBehavior);
    }

    /**
     * @param string $id
     *
     * @return boolean
     */
    public function has($id)
    {
        if (array_key_exists($id, $this->stubs)) {
            return true;
        }

        return parent::has($id);
    }
}

要启用此容器,您需要覆盖以下getContainerBaseClass方法AppKernel

/**
 * @return string
 */
protected function getContainerBaseClass()
{
    if ('test' == $this->environment) {
        return '\Zalas\Test\DependencyInjection\MockerContainer';
    }

    return parent::getContainerBaseClass();
}

您可能需要稍微调整代码,也许声明MockerContainer::$stubs为静态(尽管如果您以前的方法有效,则不需要它 - 如果您需要为多个请求存根,则可能需要它)。

现在您应该能够使用容器来存根服务,如下所示:

$client->getContainer()->stub('my_service', $myServiceStub);

使用合成服务

解决您的问题的另一种方法是将您的服务定义为综合。您可以编写一个编译器通道,它只会在测试环境中将服务标记为合成服务。

于 2017-06-17T11:17:05.487 回答
1

您的问题也在这里讨论。

你可以看看这个 osservation

请注意,在迁移到 3.3 时,您不需要修复弃用。但是当你迁移到 4.0 时你会的。

这个解决方法:

好吧,您可以标记这些测试@legacy以避免使它们暂时失败,如果需要时间的话,可以给您时间迁移测试。这是弃用的全部要点:您可以逐步迁移(我也更喜欢尽快删除弃用,但对于其中一些,可能需要更多时间)

于 2017-06-16T13:02:46.620 回答