2016-10-19 23 views
4

我需要测试以下功能:PHPUnit:如何使用多个参数模拟多个方法调用,并且没有直接的顺序?

[...] 
public function createService(ServiceLocatorInterface $serviceManager) 
{ 

    $firstService = $serviceManager->get('FirstServiceKey'); 
    $secondService = $serviceManager->get('SecondServiceKey'); 

    return new SnazzyService($firstService, $secondService); 
} 
[...] 

我知道,我可能会这样测试:

class MyTest extends \PHPUnit_Framework_TestCase 
{ 
    public function testReturnValue() 
    { 
     $firstServiceMock = $this->createMock(FirstServiceInterface::class); 
     $secondServiceMock = $this->createMock(SecondServiceInterface::class); 

     $serviceManagerMock = $this->createMock(ServiceLocatorInterface::class); 

     $serviceManagerMock->expects($this->at(0)) 
      ->method('get') 
      ->with('FirstServiceKey') 
      ->will($this->returnValue($firstService)); 

     $serviceManagerMock->expects($this->at(1)) 
      ->method('get') 
      ->with('SecondServiceKey') 
      ->will($this->returnValue($secondServiceMock)); 

     $serviceFactory = new ServiceFactory($serviceManagerMock); 

     $result = $serviceFactory->createService(); 
    } 
    [...] 

[...] 
public function testReturnValue() 
{ 
    $firstServiceMock = $this->createMock(FirstServiceInterface::class); 
    $secondServiceMock = $this->createMock(SecondServiceInterface::class); 

    $serviceManagerMock = $this->createMock(ServiceLocatorInterface::class); 

    $serviceManagerMock->expects($this->any()) 
     ->method('get') 
     ->withConsecutive(
      ['FirstServiceKey'], 
      ['SecondServiceKey'], 
     ) 
     ->willReturnOnConsecutiveCalls(
      $this->returnValue($firstService), 
      $this->returnValue($secondServiceMock) 
     ); 

    $serviceFactory = new ServiceFactory($serviceManagerMock); 

    $result = $serviceFactory->createService(); 
} 
[...] 

两个workes罚款,但如果我换了 - >在createService函数中获取(xxx)行,这两个测试都会失败。 那么,如何做我必须要改变它不需要对参数的FirstServiceKey“特定sequenz的测试用例,“SecondServiceKey,...

+0

你尝试过使用'$ this-> any()'而不是'$ this-> at(0)'? – Matteo

+0

是的,那是我第一次尝试。导致错误: 调用方法名称的期望失败等于调用零次或更多次 参数0用于调用 –

+0

是的,最初我没有仔细阅读您的问题。我希望我的回答能够满足你的需求 – Matteo

回答

4

你可以用willReturnCallbackwillReturnMap战略尝试,作为实例,willReturnCallback

public function testReturnValue() 
{ 
    $firstServiceMock = $this->createMock(FirstServiceInterface::class); 
    $secondServiceMock = $this->createMock(SecondServiceInterface::class); 

    $serviceManagerMock = $this->createMock(ServiceLocatorInterface::class); 


    $serviceManagerMock->expects($this->any()) 
     ->method('get') 
     ->willReturnCallback(
      function ($key) use($firstServiceMock, $secondServiceMock) { 
       if ($key == 'FirstServiceKey') { 
        return $firstServiceMock; 
       } 
       if ($key == 'SecondServiceKey') { 
        return $secondServiceMock; 
       } 
       throw new \InvalidArgumentException; // or simply return; 
      } 
     ); 

    $serviceFactory = new ServiceFactory($serviceManagerMock); 

    $result = $serviceFactory->createService(); 
} 

希望这有助于

0

它已经有一段时间,所以要解决这个问题一个新的选项:更改为“先知”

public function testReturnValue() 
{ 
    $this->container = $this->prophesize(ServiceLocatorInterface::class); 
    $firstService = $this->prophesize(FirstServiceInterface::class); 
    $secondService = $this->prophesize(SecondServiceKey::class); 

    $this->container->get('FirstServiceKey')->willReturn(firstService); 
    // And if you like 
    $this->container->get('FirstServiceKey')->shouldBeCalled(); 

    $this->container->get('SecondServiceKey')->willReturn(secondService); 
    [...] 
    $serviceFactory = new ServiceFactory(); 

    /* 
    * Little error in my example. ServiceLocatorInterface is parameter of 
    * createService() and not the constructor ;) (ZF2/3) 
    */ 

    $result = $serviceFactory->createService(
     $this->container->reveal() 
    ); 
    [...] 
} 

现在,没关系,你可以在'$ serviceManager-> get([...]);''电话\\/

相关问题