2017-08-03 4 views
0

私のシナリオは以下のようになります。PHPUnitのモック戻り値と異なる方法のための特定の引数を同じクラスで呼び出された回数

class ToMock 
{ 
    public function iReturn() 
    { 
     return time(); 
    } 

    public function callMe1($arg1, $arg2) 
    { 
     return true; 
    } 

    public function callMe2($arg1, $arg2) 
    { 
     return true; 
    } 
} 

class ToTest 
{ 
    public function feedMe(ToMock $toMock) 
    { 
     if ($toMock->iReturn() > 100) { 
      $toMock->callMe1(5, 10); 
     } 

     if ($toMock->iReturn() < 200) { 
      $toMock->callMe2(15, 20); 
     } 
    } 
} 

は今、私がテストしたい場合ToMock::iReturn()戻り150、ToTest::feedMe()通話ToMock::callMe1()一度で5と10、および私はまた、私は与えられた引数で一度特定の方法を期待するToMockを模擬することができ、150を返すようにToMock::iReturnを模擬することができる知っている15及び20

で一度ToMock::callMe2()。しかし、同時にこれらのすべてを一緒にすることは可能ですか?はいの場合、どのように見えるでしょうか?

答えて

1

のようになります。はい、そうです。複数の期待がexpects()、さらに制約を使用して設定されている方法

<?php 

use PHPUnit\Framework\TestCase; 

class ToTestTest extends TestCase 
{ 
    /** 
    * @dataProvider providerTimeBetween0And100 
    * 
    * @param int $time 
    */ 
    public function testFeedMeWhenTimeIsBetween0And100($time) 
    { 
     $toMock = $this->createMock(ToMock::class); 

     $toMock 
      ->expects($this->exactly(2)) 
      ->method('iReturn') 
      ->willReturn($time); 

     $toMock 
      ->expects($this->never()) 
      ->method('callMe1'); 

     $toMock 
      ->expects($this->once()) 
      ->method('callMe2') 
      ->with(
       $this->identicalTo(15), 
       $this->identicalTo(20) 
      ); 

     $toTest = new ToTest(); 

     $toTest->feedMe($toMock); 
    } 

    public function providerTimeBetween0And100() 
    { 
     return $this->providerTimeBetween(0, 100); 
    } 

    /** 
    * @dataProvider providerTimeBetween101And199 
    * 
    * @param int $time 
    */ 
    public function testFeedMeWhenTimeIsBetween101And199($time) 
    { 
     $toMock = $this->createMock(ToMock::class); 

     $toMock 
      ->expects($this->exactly(2)) 
      ->method('iReturn') 
      ->willReturn($time); 

     $toMock 
      ->expects($this->once()) 
      ->method('callMe1') 
      ->with(
       $this->identicalTo(5), 
       $this->identicalTo(10) 
      ); 

     $toMock 
      ->expects($this->once()) 
      ->method('callMe2') 
      ->with(
       $this->identicalTo(15), 
       $this->identicalTo(20) 
      ); 

     $toTest = new ToTest(); 

     $toTest->feedMe($toMock); 
    } 

    public function providerTimeBetween101And199() 
    { 
     return $this->providerTimeBetween(101, 199); 
    } 
    /** 
    * @dataProvider providerTimeGreaterThan199 
    * 
    * @param int $time 
    */ 
    public function testFeedMeWhenTimeIsGreaterThan199($time) 
    { 
     $toMock = $this->createMock(ToMock::class); 

     $toMock 
      ->expects($this->exactly(2)) 
      ->method('iReturn') 
      ->willReturn($time); 

     $toMock 
      ->expects($this->once()) 
      ->method('callMe1') 
      ->with(
       $this->identicalTo(5), 
       $this->identicalTo(10) 
      ); 

     $toMock 
      ->expects($this->never()) 
      ->method('callMe2'); 

     $toTest = new ToTest(); 

     $toTest->feedMe($toMock); 
    } 

    public function providerTimeGreaterThan199() 
    { 
     return $this->providerTimeBetween(200, 300); 
    } 

    private function providerTimeBetween($min, $max) 
    { 
     for ($time = $min; $time < $max; ++$time) { 
      yield [ 
       $time 
      ]; 
     } 
    } 
} 

注:

はここToTestをカバーテストの例です。これらはすべて簡単に組み合わせることができます。参考

、参照:

1

私が正しくあなたの質問を理解した場合、テストコードが

class MockingExpectationsTest extends PHPUnit_Framework_TestCase 
{ 
    private $obj; 
    private $mock; 

    public function setUp(){ 
     $this->mock = $this->createMock(ToMock::class); 
     $this->obj = new ToTest(); 
    } 

    public function testExpectations(){ 
     $this->mock->expects($this->exactly(2)) 
        ->method('iReturn') 
        ->willReturn(150); 
     $this->mock->expects($this->exactly(1)) 
        ->method('callMe1') 
        ->with(5, 10); 
     $this->mock->expects($this->exactly(1)) 
        ->method('callMe2') 
        ->with(15, 20); 
     $this->obj->feedMe($this->mock); 
    } 
} 
関連する問題