<?php
$mapper = $this->getMock('Bolton_MapperInterface');
$relatedMapper = $this->getMock('Bolton_MapperInterface');
$callback = function($property) use($mapper, $relatedMapper) {
if ($property == 'model') {
return $mapper;
} else if ($property == 'childModel') {
return $relatedMapper;
}
throw new Exception(sprintf('Mapper factory mock passed an unexpected parameter (%s)',$property));
};
$this->_mapperFactory->expects($this->any())->method('factory')->will($this->returnCallback($callback));
?>Mocking Objects with Final Methods in PHPUnit
Jul 8th, 2010
Having some issues with a mock in PHPUnit - the method on the mocked object was being called and the code run (bootstrap method on Zend_Application_Bootstrap_BootstrapAbstract). After some head scratching, I realized it was a final method, so PHPUnit can't override it, and thus, the code is executed. I extended Zend_Application_Bootstrap_BootstrapAbstract and overwrote the code that was cuasing problems (::bootstrap is final, but it calls ::_bootstrap, which you can override).
I 've been meaning to play around with Mockery, but until then, I've come up with some ways to deal with Mocks in PHPUnit (I personally don't think the implementation is too bad, but I'm not a die hard tester...). One of the issues I commonly run into is needing to return mocked objects from a mocked method. This is easy if the method is only called once, but what about if the same method is called a couple of times, and you need to return different mocks (e.g. ::bootstrap($name) will return different objects based on the $name parameter)?
I've used a closure with a callbackValue to get around this:
What about needing to return a different value based on the number of times the method has been called? I'll use a callback function, but then have a static variable in the callback function that keeps track of how many times it has been called. In the test setUp() method, I will reset the static variable, so the function can be used across a number of different tests.
Posted In: Zend Framework
Commentary
JohnP 2011-01-21 04:16:14
you should really try using mockery. its a whole lot better.