2015-06-16 18 views
5

Tôi đang cố gắng tạo thử nghiệm phpunit đầu tiên và thấy mình cần phải tạo phương thức trên giao diện IMailer.PHPUnit gọi đến phương thức chưa xác định `Mock_x _ :: method()`

interface IMailer 
{ 
    public function send($to, $from, $cc, $subject, $body); 
    public function sent(); 
} 

    $mailer = $this->getMockBuilder(
     'IMailer', 
     array('send', 'sent'))->getMock(); 

    $mailer->method('send')->willRreturn(0); 

Tuy nhiên, tôi tiếp tục nhận được

PHP Fatal error: 
    Call to undefined method Mock_Mailer_13fc0a04::method() 
    in ...Test.php on line 16 

một var_dump($mailer); kết quả trong

class Mock_IMailer_4c3e02a7#215 (1) { 
    private $__phpunit_invocationMocker => 
    NULL 
} 

Làm việc với đưa ra một lỗi dito - có vẻ như rằng đối tượng chế giễu không có bất kỳ giả chức năng ...

Tôi đang chạy phpunit 3.7.28 và php 5.5.9, trên một hộp ubuntu.

Bằng cách nào? Làm thế nào tôi có thể sửa chữa nó?

Trả lời

5

Hàm getMockBuilder chỉ chấp nhận tham số className làm tham số. Cách đúng để khởi tạo các phương pháp đối tượng giả của bạn sẽ được sử dụng setMethods chức năng (xem phpunit docs)

$mailer = $this->getMockBuilder('IMailer') 
     ->setMethods(array('send', 'sent')) 
     ->getMock(); 

Ngoài ra bạn có thể muốn có một số định nghĩa hy vọng cũng có khi bạn sử dụng đối tượng giả của bạn:

$mailer->expects($this->any()) 
     ->method('send') 
     ->willReturn(0); 

EDIT

Điều trên đúng với phiên bản phpunit mới hơn. Đối với phpunit 3.7.28, việc sử dụng đối tượng giả có một chút khác biệt (nghĩa là các kỳ vọng dường như là bắt buộc và sẽ không có sẵn). Đối với phiên bản 3.7.28 bạn nên sửa đổi phần thứ hai:

$mailer->expects($this->any()) 
     ->method('send') 
     ->will($this->returnValue(0)); 

Tôi muốn giới thiệu cập nhật lên phiên bản phpunit sau như nó có vẻ là hơi khó để tìm thấy tài liệu này phiên bản cũ nhiều.

+0

Cảm ơn để sửa 'getMockBuilder' gọi tôi. Tuy nhiên, 'phương thức undefined' vẫn còn ... – xtofl

+0

Đoạn mã trên chạy độc đáo không có lỗi trên phpunit 4.1.0.Bạn đã thử thêm lời gọi hàm mong đợi vào phần thứ hai ('$ mailer-> expect-> method-> willReturn')? Bạn có thể chia sẻ toàn bộ lớp kiểm tra mà bạn đang chạy không? Điều đó có thể cung cấp thêm một số manh mối cho vấn đề bạn đang gặp phải ... – ejuhjav

+1

tôi nghĩ rằng điều này nên được chấp nhận câu trả lời. -> setMethods và -> returnValue giải quyết vấn đề rất giống của tôi (cũng có vẻ như tôi có phpunit cũ) – Jimmmy

0

Một giải pháp thay thế, cho bất kỳ ai vẫn đang sử dụng phiên bản cũ của PHPUnit, nhưng vẫn muốn có thể gọi trực tiếp method(), là ghi đè lên mẫu lớp đối tượng giả định mặc định.

Sao chép MockObject/Generator/mocked_class.tpl.dist và đặt tên bản sao mocked_class.tpl. Sau đó, chỉ cần thêm the code for the method() method trong từng mẫu:

public function method() 
{ 
    $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; 
    $expects = $this->expects($any); 
    $args = func_get_args(); 
    return call_user_func_array(array($expects, 'method'), $args); 
} 

này sẽ cho phép bạn gọi $mock->method() trực tiếp. Tuy nhiên, bạn vẫn cần sử dụng ->will($this->returnValue(0)) thay vì ->willReturn(0). Để làm điều đó, bạn cần phải giới thiệu một người thợ xây custom gọi và gọi nhạo báng:

class My_MockObject_Builder_InvocationMocker 
    extends PHPUnit_Framework_MockObject_Builder_InvocationMocker { 

    public function willReturn($value) { 
     return $this->will(new PHPUnit_Framework_MockObject_Stub_Return($value)); 
    } 
} 

class My_MockObject_InvocationMocker 
    extends PHPUnit_Framework_MockObject_InvocationMocker { 

    public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) { 
     return new My_MockObject_Builder_InvocationMocker($this, $matcher); 
    } 
} 

Và cập nhật mẫu của bạn một lần nữa, để sử dụng My_MockObject_InvocationMocker thay vì PHPUnit_Framework_MockObject_InvocationMocker.

Mẫu đầy đủ sau đó sẽ trông như thế này:

{prologue}{class_declaration} 
{ 
    protected static $staticInvocationMocker; 
    protected $invocationMocker; 

{clone}{mocked_methods} 
    public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) 
    { 
     return $this->__phpunit_getInvocationMocker()->expects($matcher); 
    } 

    public function method() 
    { 
     $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; 
     $expects = $this->expects($any); 
     $args = func_get_args(); 
     return call_user_func_array(array($expects, 'method'), $args); 
    } 

    public static function staticExpects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) 
    { 
     return self::__phpunit_getStaticInvocationMocker()->expects($matcher); 
    } 

    public function __phpunit_getInvocationMocker() 
    { 
     if ($this->invocationMocker === NULL) { 
      $this->invocationMocker = new My_MockObject_InvocationMocker; 
     } 

     return $this->invocationMocker; 
    } 

    public static function __phpunit_getStaticInvocationMocker() 
    { 
     if (self::$staticInvocationMocker === NULL) { 
      self::$staticInvocationMocker = new My_MockObject_InvocationMocker; 
     } 

     return self::$staticInvocationMocker; 
    } 

    public function __phpunit_hasMatchers() 
    { 
     return self::__phpunit_getStaticInvocationMocker()->hasMatchers() || 
       $this->__phpunit_getInvocationMocker()->hasMatchers(); 
    } 

    public function __phpunit_verify() 
    { 
     self::__phpunit_getStaticInvocationMocker()->verify(); 
     $this->__phpunit_getInvocationMocker()->verify(); 
    } 

    public function __phpunit_cleanup() 
    { 
     self::$staticInvocationMocker = NULL; 
     $this->invocationMocker  = NULL; 
    } 
}{epilogue} 
Các vấn đề liên quan