2017-06-16 86 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的全新安裝上進行了測試,並且按預期工作。必須是您在項目中所做的具體事情。 –