Cannot bake ControllerTest with model type other than Table
asgraf opened this issue · comments
Description
Steps to reproduce:
- Create any controller with model type other than Table
class NbpRatesController extends AppController
{
public $modelClass = 'NbpApi.NbpRates';
public $_modelType = 'Endpoint';
//some other code
}
- 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
- Do you have Webservice plugin installed and loaded?
- 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