2016-04-21 46 views
2

我有下面的代碼被測試。在Mockery中通過代碼設置對象

// $generator, $locale, $site are parameters. 
// It is just a part of real code. 
$text = new Text(); 
$text->setType($generator->getType()) 
    ->setLocale($locale) 
    ->setSite($site->getId()); 

/** @var $site \namespace\Site */ 
$site->addText($text); 

爲了測試這個,我正在使用Mockery模擬網站。

在測試中,我一般想做

$text = $site->getText(); 
$this->assertInstanceOF('\namespace\Text', $text); 
$this->assertSame($generator->getType(), $text->getType()); 
$this->assertSame($locale, $text->getLocale()); 
$this->assertSame($site->getId(), $text->getSite()); 

同時使假,我想模擬返回由原始代碼創建,並在線路$site->addText($site)設置文本的實例。我試過

$text = new Text(); 
$site = Mockery::mock(Site::class) 
    ->shouldReceive('addText') 
    ->with($text) 
    ->andReturnUsing(function() { 
      $args = func_get_args(); 
      return $args[0]; 
     }) 
    ->getMock(); 

這樣就返回了我在模擬代碼中設置的文本對象。在嘲弄中,有什麼辦法可以讓我們在原始代碼中創建Text對象?

回答

2

在這種情況下,您可以使用Mockery::on()方法。請參閱argument validation docs。在這裏你可以傳遞一個閉包,它接收傳遞給addText方法的參數。您也可以在此閉包中使用PHPUnit斷言來對$text參數進行斷言。 這樣的問題:

$site = Mockery::mock(Site::class) 
    ->shouldReceive('addText') 
    ->with(Mockery::on(function($text) { 
     $this->assertInstanceOF('\namespace\Text', $text); 
     //More assertions 

     return true; //You must return true, otherwise the expectation will never pass regardless of the assertions above. 
    })); 
+0

謝謝@bram,我會遇到類似的問題,你給的解決方案似乎最適合我的問題。 –