0

Working my way through the levels of PHPStan with a new applicaton, I got to level 3 and started getting error messages from all my test fixtures for models. The basic format is as follows:

 ------  
  Line   tests/TestCase/Model/Table/UsersTableTest.php                                                                                           
 ------ 
  43     Property Visualize\Test\TestCase\Model\Table\UsersTableTest::$Users (Visualize\Model\Table\UsersTable) does not accept Cake\ORM\Table.  
 ------  

The code that this error refers to is:

    /**
     * setUp method
     *
     * @return void
     */
    public function setUp(): void
    {
        parent::setUp();
        $config = $this->getTableLocator()->exists('Users') ? [] : ['className' => UsersTable::class];
        $this->Users = $this->getTableLocator()->get('Users', $config);
    }

This setup code was build using cake bake, so I'm not sure what it's looking for. Does anyone else know what will resolve this issue for me?

EDITED: I did a bit of further searching. The only version of the getTableLocator() function I could find associated with this stack was in the TableRegistry class. That class in turn has a function called get() and that function does indeed return an object of type \Cake\Orm\Table:

    /**
     * Get a table instance from the registry.
     *
     * See options specification in {@link TableLocator::get()}.
     *
     * @param string $alias The alias name you want to get.
     * @param array $options The options you want to build the table with.
     * @return \Cake\ORM\Table
     * @deprecated 3.6.0 Use {@link \Cake\ORM\Locator\TableLocator::get()} instead. Will be removed in 5.0.
     */
    public static function get(string $alias, array $options = []): Table
    {
        return static::getTableLocator()->get($alias, $options);
    }

So does this mean my tests ought to expect the \Cake\ORM\Table class? TBH, I've yet to do much of anything in the way of testing Models (as you might have guessed), thus I'm not sure the consequences of doing that.

2
  • 2
    You can use inline annotations to fix that up. Or use ModelAwareTrait and loadModel() with a class annotation. There are multiple ways to tell the static analyzer the concrete type of object. Commented Jul 30, 2021 at 17:39
  • Thank you, @mark. I'm finding those annotations remarkably helpful! Commented Aug 31, 2021 at 17:58

1 Answer 1

2

The question is how to deduce from $this->getTableLocator()->get('Users', $config); that it should be returning Visualize\Model\Table\UsersTable.

You can write a dynamic return type extension if you come up with logic that can deduce that from the abstract syntax tree and maybe other places like configuration.

It's possible that the extension https://github.com/CakeDC/cakephp-phpstan might already tackle that, this class definitely looks like that: https://github.com/CakeDC/cakephp-phpstan/blob/master/src/Type/TableLocatorDynamicReturnTypeExtension.php

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.