Mocking objects in PHP has its limitations and gotchas. Some functionality can’t be mocked or can’t be mocked YET! If you locate such a circumstance, please please (pretty please with sugar on top) create a new issue on GitHub so it can be documented and resolved where possible. Here is a list to note:
- Classes containing public
__wakeup()methods can be mocked but the mocked
__wakeup()method will perform no actions and cannot have expectations set for it. This is necessary since Mockery must serialize and unserialize objects to avoid some
__construct()insanity and attempting to mock a
__wakeup()method as normal leads to a
- Classes using non-real methods, i.e. where a method call triggers a
__call()method, will throw an exception that the non-real method does not exist unless you first define at least one expectation (a simple
shouldReceive()call would suffice). This is necessary since there is no other way for Mockery to be aware of the method name.
- Mockery has two scenarios where real classes are replaced: Instance mocks
and alias mocks. Both will generate PHP fatal errors if the real class is
loaded, usually via a require or include statement. Only use these two mock
types where autoloading is in place and where classes are not explicitly
loaded on a per-file basis using
- Internal PHP classes are not entirely capable of being fully analysed using
Reflection. For example,
Reflectioncannot reveal details of expected parameters to the methods of such internal classes. As a result, there will be problems where a method parameter is defined to accept a value by reference (Mockery cannot detect this condition and will assume a pass by value on scalars and arrays). If references as internal class method parameters are needed, you should use the
- Creating a mock implementing a certain interface with incorrect case in the
interface name, and then creating a second mock implementing the same
interface, but this time with the correct case, will have undefined behavior
due to PHP’s
class_existsand related functions being case insensitive. Using the
::classkeyword in PHP can help you avoid these mistakes.
The gotchas noted above are largely down to PHP’s architecture and are assumed to be unavoidable. But - if you figure out a solution (or a better one than what may exist), let us know!