PHPUnit call for undefined method `Mock_x _ :: method ()`

I am trying to create my first phpunit test and find the need to IMailer method in the IMailer interface.

 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); 

However i keep getting

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

a var_dump($mailer); leads to

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

Working with expect($this->any()) gives a dito error - it seems that the mocking object has no functional function ...

I am running phpunit 3.7.28 and php 5.5.9 in the ubuntu field.

How did it happen? How can i fix this?

+5
source share
2 answers

The getMockBuilder function accepts only the className parameter as a parameter. The proper way to initialize mock object methods should be to use the setMethods function (see phpunit docs )

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

Also, you probably want some to expect definitions when using your mock object:

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

EDIT

The above is true for newer phpunit versions. For phpunit 3.7.28, using a mock object is slightly different (i.e., it is expected that this will be mandatory, and willReturn is not yet available). For version 3.7.28 you must change the second part:

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

I would recommend upgrading to a later version of phpunit, as it seems pretty difficult to find documentation for these older versions.

+5
source

An alternative solution for anyone who is still using older versions of PHPUnit but still wants to be able to directly call method() is to override the default object layout class template.

Copy MockObject/Generator/mocked_class.tpl.dist and name the copy mocked_class.tpl . Then just add the method() method code to the template:

 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); } 

This will allow you to directly call $mock->method() . However, you need to use ->will($this->returnValue(0)) instead of ->willReturn(0) . To do this, you need to enter a custom call builder and mocker invocation:

 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); } } 

And update your template again to use My_MockObject_InvocationMocker instead of PHPUnit_Framework_MockObject_InvocationMocker .

The full template will look like this:

 {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} 
0
source

All Articles