cakephp / bake

The Bake Command Plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot bake ControllerTest with model type other than Table

asgraf opened this issue · comments

Description

Steps to reproduce:

  1. Create any controller with model type other than Table
class NbpRatesController extends AppController
{
    public $modelClass = 'NbpApi.NbpRates';
    public $_modelType = 'Endpoint';
  
   //some other code
}
  1. bake unit test for that controller
application@d6af9a97ebb9:/application$ bin/cake bake test Controller --prefix=Admin --plugin=SuperAdmin NbpRates
Bake is detecting possible fixtures...

2023-10-05 16:33:22 error: [TypeError] Bake\Command\TestCommand::_processModel(): Argument cakephp/cakephp#1 ($subject) must be of type Cake\ORM\Table, NbpApi\Model\Endpoint\NbpRatesEndpoint given, called in /application/vendor/cakephp/bake/src/Command/TestCommand.php on line 502 in /application/vendor/cakephp/bake/src/Command/TestCommand.php on line 465
Stack Trace:
- /application/vendor/cakephp/bake/src/Command/TestCommand.php:502
- /application/vendor/cakephp/bake/src/Command/TestCommand.php:452
- /application/vendor/cakephp/bake/src/Command/TestCommand.php:258
- /application/vendor/cakephp/bake/src/Command/TestCommand.php:132
- /application/vendor/cakephp/cakephp/src/Console/BaseCommand.php:189
- /application/vendor/cakephp/cakephp/src/Console/CommandRunner.php:334
- /application/vendor/cakephp/cakephp/src/Console/CommandRunner.php:172
- /application/bin/cake.php:12

[TypeError] Bake\Command\TestCommand::_processModel(): Argument cakephp/cakephp#1 ($subject) must be of type Cake\ORM\Table, NbpApi\Model\Endpoint\NbpRatesEndpoint given, called in /application/vendor/cakephp/bake/src/Command/TestCommand.php on line 502 in /application/vendor/cakephp/bake/src/Command/TestCommand.php on line 465

Stack Trace:

#0 /application/vendor/cakephp/bake/src/Command/TestCommand.php(502): Bake\Command\TestCommand->_processModel(Object(NbpApi\Model\Endpoint\NbpRatesEndpoint))
cakephp/cakephp#1 /application/vendor/cakephp/bake/src/Command/TestCommand.php(452): Bake\Command\TestCommand->_processController(Object(SuperAdmin\Controller\Admin\NbpRatesController))
cakephp/cakephp#2 /application/vendor/cakephp/bake/src/Command/TestCommand.php(258): Bake\Command\TestCommand->generateFixtureList(Object(SuperAdmin\Controller\Admin\NbpRatesController))
cakephp/cakephp#3 /application/vendor/cakephp/bake/src/Command/TestCommand.php(132): Bake\Command\TestCommand->bake('Controller', 'NbpRates', Object(Cake\Console\Arguments), Object(Cake\Console\ConsoleIo))
cakephp/cakephp#4 /application/vendor/cakephp/cakephp/src/Console/BaseCommand.php(189): Bake\Command\TestCommand->execute(Object(Cake\Console\Arguments), Object(Cake\Console\ConsoleIo))
cakephp/cakephp#5 /application/vendor/cakephp/cakephp/src/Console/CommandRunner.php(334): Cake\Console\BaseCommand->run(Array, Object(Cake\Console\ConsoleIo))
cakephp/cakephp#6 /application/vendor/cakephp/cakephp/src/Console/CommandRunner.php(172): Cake\Console\CommandRunner->runCommand(Object(Bake\Command\TestCommand), Array, Object(Cake\Console\ConsoleIo))
cakephp/cakephp#7 /application/bin/cake.php(12): Cake\Console\CommandRunner->run(Array)
cakephp/cakephp#8 {main}

CakePHP Version

4.4.17

PHP Version

8.1

Side note:

protected ?string $modelClass = null;

those are both protected ones
but this wouldnt directly be related to the issue of course.

I couldnt reproduce this with Admin routes inside app:

devilbox@php-8.1.13 in /shared/httpd/sandbox $ bin/cake bake test Controller --prefix=Admin Rates
Bake is detecting possible fixtures...

Baking test case for App\Controller\Admin\RatesController ...

Wrote `/shared/httpd/sandbox/tests/TestCase/Controller/Admin/RatesControllerTest.php`
Done

The controller contained the two lines

public $modelClass = 'NbpApi.NbpRates';
public $_modelType = 'Endpoint';

Source of this bug is the fact that baking test for Controller also triggers fixture baking logic.
This logic currently is implemented as:

protected function _processModel(Table $subject): void

So when $subject takes value of \Muffin\Webservice\Model\Endpoint (or other non-table object) then exception is thrown

Solution would be to change it to:

protected function _processModel(RepositoryInterface $subject): void
    if (!method_exists($subject, 'associations')) {
        return;
    }

I couldnt reproduce this

  1. Do you have Webservice plugin installed and loaded?
  2. does $this->loadModel() inside your controller returns instance of \Muffin\Webservice\Model\Endpoint class?

Please notice that when $controller->loadModel() throws UnexpectedValueException fixture baking logic is skipped and then baking ControllerTest completes successfully

@asgraf A patch would be welcome to resolve the issue. Though instead of using a method_exists() check as you suggested, checking whether the subject is an instance of Table would be better.

@asgraf A patch would be welcome to resolve the issue. Though instead of using a method_exists() check as you suggested, checking whether the subject is an instance of Table would be better.

Usage of method_exists instead of hard-coding check for Table instance was intentional.
I can imagine other repository types with support for associations. Why hard-code that?

To date I haven't come across any implementation of non db repository which has associations. Also the code assumes the association classes are the database specific ones used in the core ORM. It's highly unlikely the code will work with any other user implemented association classes.

Feel free to modify my pull requests

This issue is stale because it has been open for 120 days with no activity. Remove the stale label or comment or this will be closed in 15 days