How to properly inject an association for a test

Hi!

Can anyone tell me what is the intendend way to mock an association without getting a deprecation warning.

In my TestSetup I load a Model like this:

$this->Orders = $this->getTableLocator()->get('Orders');

In the actual Test I inject an association

$this->Orders->Tickets = $this->getMockForModel('Tickets', ['reverse']);

But this gives a deprecation warning

Creation of dynamic property is deprecated

I have seen that I could add

use \AllowDynamicProperties;

to the Orders class. But I don’t like to modify the production code just to get it working. I also tried to inject it into the associations() which is used in the __get() method, but that does not work as the mock is not of the correct type.

Could you do $this->Orders->addAssociations($params);?

I haven’t actually tried this, but in my CakePHP5 install it seems a likely candidate.

I don’t think so. addAssociations takes an array and just forwards to hasMany(), belongsTo etc. And those functions use the load() method to load the tables - so also no possibility to inject it.

getMockForModel() will return you the mock instance which is already set in the TableLocator.

Therefore, any code after this call will already use your mock, you don’t have to set it manually on the table instance.

You just have to configure the mock however you like.

So the recommended way would be to mock also the $this->Orders to be able to mock the associations?

No, if you just call

$this->getMockForModel('Tickets', ['reverse']);
$this->get(['controller' => 'Orders', 'action' => 'index']);

then the table instance which you will access via

$this->Orders->Tickets

inside your app will already be the mocked one.

The Orders table will be the normal one.

Wow - works perfect!