CakePHP 2 Unit Test Mocking — Prevent assigning different Alias
Problem: Mock
If you have tried Mocking models, you might have encountered some problems especially for models that have Associations. One of those problem is, when you mock a model, it assigns an alias.
For example: model User will become Mock_User_b13d6ac9.
That will cause a lot of conflicts and one of them that I have encountered is, when I used the Containable behavior.
Solution
Let us check first the function for mocking, which in my case, I use TestCase::getMock()
. These are the arguments that the function getMock
accepts.
public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE) { ...
The parameters that is going to fix our problem will be the $arguments
parameter.
If you’ll check the documentation of getMock
function, the purpose of parameter $arguments
is:
Parameters to pass to the original class’ constructor.
In this case, it will pass it to User model’s constructor. The User.php
model extends the class Model.php
. Now let us check the constructor of Model.php
:
public function __construct($id = false, $table = null, $ds = null) { ...
The parameter that we will be needing is the $id
parameter. Now let us check the documentation of parameter $id
:
* If `$id` is an array it can be used to pass several options into the model. * * - `id`: The id to start the model on. * - `table`: The table to use for this model. * - `ds`: The connection name this model is connected to. * - `name`: The name of the model eg. Post. * - `alias`: The alias of the model, this is used for registering the instance in the `ClassRegistry`. * eg. `ParentThread`
As you can see, we can pass an array as a value to parameter $id
. So what we will have to set is the name
key. We are going to set the original alias in this key and that would fix our problem.
Eg.
$Mock = $this->getMock('User', ['getById'], ['id' => ['name' => 'User']]); $Mock->expects($this->any())->method('getById')->will($this->returnValue(['User' => []])); $this->User = $Mock;
Now if you try to run debug($this->User->alias)
, we could see that it’s now using User instead of generating an alias with a random key like Mock_User_b13d6ac9.