PHPUnit: stub methods undefined

mocking, php, phpunit, unit-testing

Solution

Answering my own question:

After quite a bit of frustration, I did manage to get things working. I'm not sure precisely what the issue was, but did discover a few things that might help others:

- Make sure you're running the latest version of PHPUnit (3.4.6 as of this writing)

Use the fully-qualified namespace minus the first backslash.

$this->getMock('MyApp\Widgets\WidgetFactory');

Part of my problem was that PHPUnit was creating a stub class `WidgetFactory` that was not actually stubbing `MyApp\Widgets\WidgetFactory`. One would expect that an exception would occur if trying to stub a non-existent class, but it doesn't seem to happen with the namespace confusion.

Also, there is a question over here that suggests using the class alias method as follows:

    class_alias('MyApp\Widgets\WidgetFactory', 'WidgetFactory');
    $this->getMock('WidgetFactory');

While this did temporarily solve my problem, I would strongly advise against using it. `class_alias()` cannot be called twice for the same alias without raising an exception, which causes obvious problem if used in the `setup()` method, or as part of the stub generation.

Problem

I must be missing something. I'm trying to stub methods on a class in PHPUnit, but when I invoke the method on the mock object, it tells me that method is undefined. Example class to stub: ``` namespace MyApp; class MyStubClass { public function mrMethod() { // doing stuff } } ``` To stub it, I write: ``` // specifying all getMock() args to disable calling of class __construct() $stub = $this->getMock('MyStubClass', array(), array(), 'MockMyStubClass', false, false, false); $stub->expects($this->any()) ->method('mrMethod') ->will($this->returnValue('doing stuff')); ``` But upon invoking the stubbed method, I get an exception: ``` $stub->mrMethod(); //PHP Fatal error: Call to undefined method MockMyStubClass::mrMethod() ``` I'm using PHPUnit 3.4.3 with PHP 5.3.0. Another small thing I noticed was that if specifying a namespace in the `getMock()` method results in a class loading exception because of a double namespace: ``` $stub = $this->getMock('MyApp\MyStubClass'); // Fatal error: Class 'MyApp\MyApp\MyStubClass' not found ``` That strikes me as rather odd (and getmock() will not accept a namespace with a leading backslash). The only thing I could think to cause that would may be because this class is registered with an autoloader? Any thoughts?

Original source

Related problems