2017-06-16 82 views
1

今天,我试图将我的项目升级到新版本的Symfony(3.3),并且我遇到了我的模拟问题。模拟调用外部API

直到今天,我在做我的嘲笑这样的:

$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只是一个暴食后,没有别的。现在

,我发现了以下错误:

Setting the "my_service" pre-defined service is deprecated since Symfony 3.3 and won't be supported anymore in Symfony 4.0: 1x

经过一番研究,看来我不能用我的代码的最后一行。 问题是,我看不到也没有找到任何解决方案来解决这个问题。

回答

1

你的问题也讨论here

您可以在this osservation看一看:

Note that you don't need to fix the deprecations when moving to 3.3. But you will when moving to 4.0.

而且this workaround

Well, you can mark these tests as @legacy to avoid making them fail temporarily, to give you time to migrate the tests, if that takes time. This is the whole point of deprecations: you can migrate progressively (I also prefer removing deprecations as fast as possible, but for some of them, it may require more time)

+1

谢谢你的回复。我已经看到了这个讨论,并且我看到我的项目采用了同样的方式[xkobal](https://github.com/symfony/symfony/pull/21533#issuecomment-302105140) 另外,我不想要我的测试作为遗产,它必须工作。在讨论中没有真正的解决方案,只是“这是正常的”,“传统”,“现在不需要”...... –

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

使用综合服务

在你的问题的工作是定义你的服务为synthetic的另一种方式。您可以编写一个编译器通行证,仅在测试环境中将服务标记为综合。

+0

我试过了第二种方法(我得到的唯一一种方法),而且我有一个段错误我必须做的第二个模拟测试。任何想法? –

+0

我刚刚在Symfony的全新安装上进行了测试,并且按预期工作。必须是您在项目中所做的具体事情。 –