Question

PHPUnit mock objects and method type hinting

I'm trying to create a mock object of \SplObserver using PHPunit and attach the mocked object to an \SplSubject. When I try to attach the mocked object to a class that implements \SplSubject, I get a catchable fatal error saying that the mocked object doesn't implement \SplObserver:

PHP Catchable fatal error:  Argument 1 passed to ..\AbstractSubject::attach() must implement interface SplObserver, instance of PHPUnit_Framework_MockObject_Builder_InvocationMocker given, called in ../Decorator/ResultCacheTest.php on line 44 and defined in /users/.../AbstractSubject.php on line 49

More or less, here's the code:

// Edit: Using the fully qualified name doesn't work either
$observer = $this->getMock('SplObserver', array('update'))
    ->expects($this->once())
    ->method('update');

// Attach the mock object to the cache object and listen for the results to be set on cache
$this->_cache->attach($observer);

doSomethingThatSetsCache();

I'm not sure if it makes a difference, but I'm using PHP 5.3 and PHPUnit 3.4.9

 45  13330  45
1 Jan 1970

Solution

 81

Update

Oh, actually, the problem is pretty simple, but somehow hard to spot. Instead of:

$observer = $this->getMock('SplObserver', array('update'))
                 ->expects($this->once())
                 ->method('update');

You have to write:

$observer = $this->getMock('SplObserver', array('update'));
$observer->expects($this->once())
         ->method('update');

That's because getMock() returns a different thing than method(), that's why you got the error. You passed the wrong object to attach.

Original answer

I think you have to fully qualify the type of the mock:

$observer = $this->getMock('\SplObserver', array('update'));
2010-07-11