2015-10-30 52 views
0

我的問題是。我有一個我想測試的課程(myClass)。在myClass中有一個函數,它也調用了myClass中的私有函數。告訴phpunit打電話給公衆而不是私人的

我知道我不能測試私人功能。是否有可能告訴phpunit調用另一個函數而不是私有的?

$this->testclass現在我想測試

$this->testclass = new \stdClass(); 
$this->testclass->mock = $this->getMockBuilder('myClass')->getMock(); 

超出了我的測試用例我創建了一個假類的類。

$this->mockextended = new \stdClass(); 
$this->mockextended->mock = new MOCKEXTENDEDCLASSES(); 

$this->mockextended我有一個公共功能。

我想要的功能測試

public function TestMe(){ 
$this->somePrivateFunctioniHate(); <==== this is the pain in my ass 
} 

和私有函數

private function somePrivateFunctioniHate(){ 
    //come code 
    } 

我想要做的是什麼。函數TestMe正在調用一個私有函數。 是否有可能告訴phpunit覆蓋私人功能,並調用$this->mockextended; 內部的其他功能我已經嘗試過這樣。

$this->testclass->somePrivateFunctioniHate() = $this->mockextended->theWholeNewPrivateFunction() 

只有這給了我一個很好的錯誤。我之前做過,並且工作。這樣稱呼它

編輯 對於不明白我的問題的人。 我有另一個調用另一個類的函數。我不想在我的測試中再添加一門課,所以我在測試用例外部創建了一個假類。插入與函數想要包含的類相同的功能。難道這樣嗎?

$this->testclass->chunks = new \stdClass(); 
    //MOCKchunckTpl is the fake class outside my testcase 
      $this->testclass->chunks->config = new MOCKchunkTpl(); 

This works。每當一個功能想打電話$this->testclass->chunks->config->Somefunction();它將被重定向到我的假類。

但是當我試圖做一個函數調用私人函數相同。像$this->testclass->somePrivateFunctioniHate() = $this->mockextended->theWholeNewPrivateFunction()它給出了一個很好的錯誤

Fatal error: Can't use method return value in write context in 
+1

爲什麼在用你的模擬填充相同的變量之前,你總是實例化一個'new \ stdClass()'? – StoryTeller

+0

我希望它使用它像$ object->其他對象 - > anotherobject-> thisonetoo ...... –

+1

但是,您正在覆蓋變量立即。在這兩種情況下,'stdClass'會丟失,實例化沒有意義。那麼, – StoryTeller

回答

2

簡答:不,沒有。 PHPUnit無法操作私有方法。

模仿是爲了僞造類的行爲,這取決於你想測試的類。如果您需要覆蓋私有方法,那麼您的體系結構中會出現問題。應該通過簡單測試使用它們的公共方法來測試私有方法。如果您需要單獨測試,請將其公開。

編輯:下面是一個例子,你會如何使用私有方法或者把這個私有方法在另一個類中測試一個簡單的代碼:

1.私有方法

class MyClass { 

    public function myMethod() { 
     return $this->myPrivateMethod(); 
    } 

    private function myPrivateMethod() { 
     return 2; 
    } 

} 

並且測試等級:

class MyClassTest extends \PHPUnit_Framework_TestCase { 

    public function testMyMethod() { 
     $myClass = new MyClass(); 
     // don't mind the private method, just test if the public method is working 
     $this->assertEquals(2, $myClass->myMethod()); 
    } 

} 

1. S的Econd類

class MyClass { 

    public $dependentClass; 

    public function myMethod() { 
     return $this->dependentClass->dependentMethod(); 
    } 

} 

而且依賴類:

class DependentClass { 

    public function dependentMethod() { 
     return 38943; 
    } 

} 

測試MyClassDependentClass

class MyClassTest extends \PHPUnit_Framework_TestCase { 

    public function testMyMethod() { 
     $dependentMock = $this->getMockBuilder("DependentClass")->getMock(); 
     $dependentMock->expects($this->any()) 
      ->method("dependentMethod") 
      ->willReturn($this->returnValue(2)); 

     $myClass = new MyClass(); 
     $myClass->dependentClass = $dependentMock; 

     $this->assertEquals(2, $myClass->myMethod()); 
    } 

雖然我們定義在DependentClass完全是另外一個回報,測試仍然會通過,因爲我們嘲笑它並能夠定義我們預期的所有行爲DependentClass

但是要乾淨地測試項目,我們需要定義另一個測試DependentClass以及測試,如果這個類正在工作。如果測試不再工作,該測試應該失敗,而不是MyClass的測試。

+0

中提到這個問題。爲什麼它與我在我的問題中給出的最後一個例子一起工作? $ this-> testclass-> mock-> config = new someClass(); // <==像魅力一樣工作 –

+0

在這種情況下,您並未使用要測試的類的私有方法,而是使您的類依賴於另一個類。這是模擬對象的經典用例。所以通常你不會創建一個虛假的類,而是獲得你注入類的模擬對象並調用它的方法。 – StoryTeller