2010-07-21 30 views
17

Tôi đang cố gắng để cấu hình một đối tượng Mock trong PHPUnit trở lại giá trị cho các thuộc tính khác nhau (được truy cập bằng cách sử dụng chức năng __get)PHPUnit - tạo các đối tượng Mock để hoạt động như khai đối với tài sản

Ví dụ:

class OriginalObject { 
public function __get($name){ 
switch($name) 
case "ParameterA": 
    return "ValueA"; 
case "ParameterB": 
    return "ValueB"; 
} 
} 

tôi đang cố gắng để thử này sử dụng:

$mockObject = $this->getMock("OrigionalObject"); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue("ValueA")); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue("ValueB")); 

nhưng điều này không khủng khiếp :-(

+1

Có phải lỗi chính tả ("Origional" thay vì "gốc", thiếu dấu ngoặc kép đóng cửa ở mức ValueA và VALUE tỷ) trong mô hình mã một phần của mã thực tế của bạn, hoặc lỗi phiên mã? – Phil

+1

LOL Cảm ơn Phil (vì đã chỉ ra chứng khó đọc của tôi) Lỗi chính tả (sửa đổi ngay) chỉ trong mã ví dụ - rõ ràng đây không phải là mã thực tế đang được thực thi – Tim

Trả lời

9

tôi đã không cố gắng chế giễu __get nêu ra, nhưng có lẽ điều này sẽ làm việc:

// getMock() is deprecated 
// $mockObject = $this->getMock("OrigionalObject"); 
$mockObject = $this->createMock("OrigionalObject"); 

$mockObject->expects($this->at(0)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue('ValueA')); 

$mockObject->expects($this->at(1)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue('ValueB')); 

Tôi đã sử dụng $ this-> ở() trong một thử nghiệm và nó hoạt động (nhưng không phải là một giải pháp tối ưu) . Tôi đã nhận nó từ tread này:

How can I get PHPUnit MockObjects to return different values based on a parameter?

+0

hey koen $ this-> at() làm việc cho tôi - Cảm ơn bạn ;-) Tại sao bạn không nghĩ rằng đây là giải pháp tối ưu? – Tim

+1

Nó không thực sự khả năng mở rộng và thử nghiệm rất khó đọc. Một cuộc gọi lại có thể dễ đọc hơn nếu bạn cho nó một cái tên hay. Nhưng ngay từ đầu, tôi sẽ xem xét cố gắng tái cấu trúc __get. – koen

+0

cũng có, bạn đang thử nghiệm nhà nước (mà một số coi là thực hành xấu) và thậm chí nhiều hơn, tư nhân nhà nước (mà nhiều người coi là một thực tế xấu). Tất nhiên có những người thông minh, những người không nhìn thấy một vấn đề trong đó và bạn có thể là một trong số họ. – koen

4

này nên làm việc:

class Test extends \PHPUnit_Framework_TestCase { 
... 
    function testSomething() { 
     $mockObject = $this->getMock("OrigionalObject"); 

     $mockObject 
       ->expects($this->any()) 
       ->method('__get') 
       ->will($this->returnCallback('myMockGetter')); 
     ... 
    } 
... 
} 

function myMockGetter($classPropertyName) { 
    switch($classPropertyName) { 
     case 'ParameterA': 
      return 'ValueA'; 

     case 'ParameterB': 
      return 'ValueB'; 
    } 
} 
... ... 
+0

Tôi nghĩ giải pháp của tôi tối ưu hơn koen, nhưng anh ấy đã đưa ra một số điểm quan trọng trong nhận xét của mình. Tôi nghĩ rằng một giải pháp có thể là tạo một lớp thử nghiệm và không sử dụng một đối tượng giả. Điều này thường được sử dụng cho những thứ như bộ điều hợp HTTP. –

Các vấn đề liên quan