2014-04-23 88 views
1

我正在爲使用名爲Httpful的第三方工具的REST服務連接器編寫單元測試。PHPUnit模擬覆蓋現有方法

因爲我不想真正的請求發送到服務器,我從Httpful嘲笑「發送」方法\索取:

$mockedRequest = $this->getMock('Httpful\Request', array('send'), array(), '', false); 
$mockedRequest->expects($this->once())->method('send'); 

這工作得很好,但請求類有一個叫方法預計本身,我用我的實際代碼來定義可接受的MIME類型的響應。

$this 
    ->getRequest('GET') 
    ->uri(ENDPOINT . $configurationId) //by default this returns a Request Object (now mocked request) 
    ->expects('application/json') //crashes ... 
    ->send(); 

當代碼被執行,我得到以下錯誤(這是可以理解的):傳遞給Mock_Request_938fb981

參數1 ::預期()必須實現接口PHPUnit_Framework_MockObject_Matcher_Invocation,串給出

是否有類似於「期望」的來自Mock類的方法的可配置前綴?

回答

1

我不認爲你將能夠做到這一點使用PHPUnit_MockObject類。但是你可以自己編碼並使用它。

class MockRequest extends \Httpful\Request { 

    public $isSendCalled = false; 
    public $isUriCalled = false; 
    public $isExpectsCalled = false; 

    public function uri($url) { 
     if($url !== '<expected uri>') { 
      throw new PHPUnit_Framework_AssertionFailedError($url . " is not correct"); 
     } 
     $this->isUriCalled = true; 
     return $this; 
    } 

    public function expects($type) { 
     if($type !== 'application/json') { 
      throw new PHPUnit_Framework_AssertionFailedError($type . " is not correct"); 
     } 
     $this->isExpectsCalled = true; 
     return $this; 
    } 

    public function send() { 
      $this->isSendCalled = true; 
    } 
} 

您創建模擬然後行只是變成了:

$mockedRequest = new MockRequest(); 

如果構造FO

然後在您的測試,你可以驗證該方法被調用

$this->assertTrue($mockedRequest->isSendCalled); 
$this->assertTrue($mockedRequest->isUriCalled); 
$this->assertTrue($mockedRequest->isExpectsCalled); 

這不是一個非常動態的模擬,但它會通過類型暗示,併爲您檢查。我會在與你的測試相同的文件中創建這個模擬(儘管要小心不要在你的測試套件的其他地方無意中重新定義這個類)。但它會讓你圍繞期待被覆蓋的問題。

PHPUnit_Framework_MockObject_MockObject是一個接口,它爲expects()設置也是你的類不符合的簽名,所以如果你能夠重命名該方法將會出錯。

https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/src/Framework/MockObject/MockObject.php