2011-03-02 59 views
3

我有一個我想模擬的接口,並模擬其中一個方法的行爲。在PHPUnit中嘲諷時通過引用傳遞

所以我創建了一個回調,嘲諷非常簡單的行爲。

如果我創建一個基於此接口的新對象,則此測試通過,但我想模擬該接口。

模擬的setUp方法被稱爲罰款,並在我的回調中調用getVar('testing')返回值。但是我的斷言失敗了,因爲這個值是不可用的。

看來你不能在PHPUnit中做到這一點?除非我很愚蠢。

代碼流的簡要說明; 「getVar」中的代碼調用一個方法,在添加的插件上調用「setUp」。當它調用「setUp」時,它傳遞「$ this」。這是我期望通過引用傳遞的,並且與「真實」對象一起工作。

class DefaultRendererTest extends \PHPUnit_Framework_TestCase 
{ 

    public function testSetGetVar() 
    { 
     $theme = $this->getMock('ThemeInterface'); 

     $plugin = $this->getMock('PluginInterface'); 
     $plugin->expects($this->once()) 
      ->method('setUp') 
      ->will($this->returnCallback(function($r){ 

       $r->setVar('testing', "fooBar"); 

     })); 

     $renderer = new DefaultRenderer($theme, null); 
     $renderer->addPlugin($plugin); 
     $this->assertEquals('fooBar',$renderer->getVar('testing')); 
    } 
} 

對於這裏的信息是在接口方面,DefaultRenderer實現RendererInterface

interface PluginInterface 
{ 
    function setUp(RendererInterface $renderer); 
} 
+0

看起來完全適合我。你有沒有檢查$ r和$ renderer是否實際上是對同一個對象的引用?雖然,我沒有看到他們不應該這樣做的原因。也許有setVar()或getVar()中的錯誤? – tobyS

回答

4

OK,出於興趣,我就找到了這個問題。似乎PHPUnit在實際調用發生之前自動克隆參數。我沒有看到真正的原因,但也許有一個。看看Framework/MockObject/Invocation/Static.php,如何避免這種情況(基於內置的模擬代碼)只有一種方法:在DefaultRenderer中實施專用的__clone()方法。

我也建議你在IRC或PHPUnit郵件列表上詢問這種行爲或模擬對象庫。

+3

塞巴斯蒂安已經表示,他不確定這是否是正確的行爲,但沒有做出最終決定。這將有助於提供反饋,說明克隆是錯誤的行爲。 –

+1

_(相關)_(要添加到Davids正確的評論):我有同樣的問題/問題,並問塞巴斯蒂安關於它:http://stackoverflow.com/questions/4702132/problem-with-returncallback-of- PHPUnit的-嘲笑/ 4711782#4711782 – edorian