2013-02-27 31 views
10

Tôi gặp sự cố khi mô phỏng phương thức __get ($ index) quá tải. Mã cho lớp để nhạo báng và hệ thống được kiểm tra mà tiêu thụ nó như sau:PHPUnit: Mocking __get() kết quả trong "__get() phải lấy chính xác 1 đối số ..."

<?php 
class ToBeMocked 
{ 
    protected $vars = array(); 

    public function __get($index) 
    { 
     if (isset($this->vars[$index])) { 
      return $this->vars[$index]; 
     } else { 
      return NULL; 
     } 
    } 
} 

class SUTclass 
{ 
    protected $mocky; 

    public function __construct(ToBeMocked $mocky) 
    { 
     $this->mocky = $mocky; 
    } 

    public function getSnack() 
    { 
     return $this->mocky->snack; 
    } 
} 

thử nghiệm trông như sau:

<?php  
class GetSnackTest extends PHPUnit_Framework_TestCase 
{ 
    protected $stub; 
    protected $sut; 

    public function setUp() 
    { 
     $mock = $this->getMockBuilder('ToBeMocked') 
        ->setMethods(array('__get') 
        ->getMock(); 

     $sut = new SUTclass($mock); 
    } 

    /** 
    * @test 
    */ 
    public function shouldReturnSnickers() 
    { 
     $this->mock->expects($this->once()) 
        ->method('__get') 
        ->will($this->returnValue('snickers'); 

     $this->assertEquals('snickers', $this->sut->getSnack()); 
    } 
} 

mã thực là phức tạp hơn một chút, mặc dù không nhiều, có "getSnacks()" trong lớp cha của nó. Nhưng ví dụ này là đủ.

Vấn đề là tôi nhận được lỗi sau, khi thực hiện các thử nghiệm với PHPUnit:

Fatal error: Method Mock_ToBeMocked_12345672f::__get() must take exactly 1 argument in /usr/share/php/PHPUnit/Framework/MockObject/Generator.php(231) 

Khi tôi gỡ lỗi tôi thậm chí không thể đạt được phương pháp thử nghiệm. Có vẻ như nó phá vỡ lúc thiết lập đối tượng giả.

Bất kỳ ý tưởng nào?

+0

OK, tôi đã thử nghiệm thêm một chút. Vấn đề thực sự có vẻ là xây dựng lớp học chế nhạo. Nếu tôi tạo nó bằng -> setMethods (mảng ('blabla')), anh ta sẽ được thử nghiệm. Nếu tôi sử dụng -> setMethods (mảng ('__ get')) anh ta phá vỡ. – beToiba

+0

Bạn nói đúng - vấn đề là phải làm gì với việc các đối tượng giả lập PHP đang tạo ra mô hình như thế nào - không có câu trả lời nào dưới đây giải quyết vấn đề này. Tôi nhận được vấn đề này trong PHPUnit 4.0 - bạn đang sử dụng phiên bản nào? – HorusKol

+0

Tôi đã cố gắng tạo lại điều này với các kết hợp khác nhau của phiên bản PHPUnit và phụ thuộc Mock Object từ phiên bản mới nhất có sẵn (4.8.2 tại thời điểm viết) trở lại PHPUnit 3.5 và không thể phá vỡ theo cách này bằng cách sử dụng môi trường - PHP 5.5 trên Ubuntu 12.04.5 LTS. Trừ khi áp phích gốc có thể mở rộng về câu hỏi này bằng cách ghi nhớ sự kết hợp của các phiên bản mà họ đang sử dụng, tôi khuyên bạn nên đóng câu hỏi này. – Benjamin

Trả lời

0

Bạn có thể thử nó với returnCallback thay vì returnValue:

$this->mock->expects($this->once()) 
    ->method('__get') 
    ->will($this->returnCallback(array($this, 'callbackMethod'))); 

Mà sau đó sẽ gọi phương thức callbackMethod với các thông số __get được gọi.

phương pháp gọi lại bạn có thể trông tương tự như sau:

public function callbackMethod() 
{ 
    return 'snickers'; 
} 

Xem: http://www.phpunit.de/manual/3.5/en/test-doubles.html#test-doubles.stubs.examples.StubTest5.php

+1

Cảm ơn gợi ý, nhưng điều đó dường như không phải là vấn đề. Nó thực sự có vẻ là tại điểm tạo giả. – beToiba

+0

Tuyệt vời, chính xác những gì tôi cần! –

-1

__get() có một đối số, vì vậy bạn cần phải cung cấp mô hình với một:

/** 
* @test 
*/ 
public function shouldReturnSnickers() 
{ 
    $this->mock->expects($this->once()) 
       ->method('__get') 
       ->with($this->equalTo('snack')) 
       ->will($this->returnValue('snickers'); 

    $this->assertEquals('snickers', $this->sut->getSnack()); 
} 

Phương thức with() đặt đối số cho phương thức được giả lập trong PHPUnit. Bạn có thể tìm thêm chi tiết trong phần trên Test Doubles.

+0

Việc đưa vào cuộc gọi 'with()' là những gì tôi mong đợi để sửa lỗi này, nhưng nó không cho tôi (PHPUnit 4.4). Bạn đã * thử nghiệm * câu trả lời này trước khi đưa nó? Chỉ cần tự hỏi nếu bạn chỉ đơn giản là regurgitating các tài liệu, hoặc biết điều này để làm việc? –

+0

Tôi nghĩ rằng tôi đã sử dụng 3,7 vào thời điểm đó. Điều này (hoặc một cái gì đó như nó) đã làm việc, nhưng tôi không thể tìm thấy những gì tôi đã tham khảo khi tôi đã viết này. Nhưng không, tôi đã thử nghiệm mã này. – mAAdhaTTah

+0

Chúc mừng. Tôi phải làm điều gì đó daft (một chút của một newbie PHP) –

-1

withAnyParameters() phương pháp có thể giúp bạn, công trình này đúng:

$this->mock -> expects($this -> once()) 
    -> method('__get') -> withAnyParameters() 
    -> will($this -> returnValue('snikers')); 
0

Look trong phương pháp __get ma thuật chế giễu. Có lẽ bạn gọi đó là một phương thức __get khác từ phương thức khác và không phải đối tượng được chế nhạo đúng cách.

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