Making Tables that only are used in tests

I’m working on some code that will eventually be a plugin.

While testing the code I need some tables but those tables are not required by the plugin, they would come from the app that uses the plugin. So I don’t want the Table or Entity classes to be in my plugin code base.

I was thinking I could do something like this and have those classes sequestered with my other test files:

Screen Shot 2023-10-30 at 11.48.32 AM

Though I can filter my phinx migrations so the testing tables only exist in the test db, I’m having trouble baking the classes and having them work from this location. FixtureFactory seems especially opposed to this approach.

So I’m looking for some general advice on how I should be approaching this problem.

You can either use what the cakephp core does itself via SchemaLoader::loadInternalFile

which works across all DBMS :wink:


Or use the other public method on that class SchemaLoader::loadSqlFiles

which instead of using the array schema syntax just lets you define a path to a SQL file. This of course can be a bit limiting if you want to do testing on multiple DBMS

thanks, I’ll look into those.

Notes about my solution

@KevinPfeifer’s suggestions were useful and instructive but didn’t quite satisfy my need. Truth is, my phinx migrations that build the template tables in the testing db brought me to the same point.

Its possible to get a generic Table and Entity objects using $this->getTableLocator()->get('SomeAlias') based on bootstrapped or phinx created schemas.

However I needed the fixtures to return entities that also implemented another interface that was part of my design. The generic objects wouldn’t do.

Mocks

It’s possible I could write my classes then mock them for my tests and I may end up doing that in some tests.

But I was hooked on the question of whether my idea was possible.

The Real Deal

Writing the required Table and Entity classes in the directories I suggested worked fine. Just get the namespaces correct. The only change from normal was in the Table class where I had to implement:

//in Table class
    /**
     * Returns the database connection name to use by default.
     *
     * @return string
     */
    public static function defaultConnectionName(): string
    {
        return 'test';
    }

No surprise there.

The FixtureFactory could also be written as normal with two changes:

//In the SpecialTestingFactory class

//import the new table along with the other dependencies
use App\Test\src\Model\Table\SpecialTestingTable;

//identify this Table as the source for the factory
    /**
     * Defines the Table Registry used to generate entities with
     *
     * @return string
     */
    protected function getRootTableRegistryName(): string
    {
        return SpecialTestingTable::class;
    }

Notes on baking

Baking rather than hand writing these classes was possible but took a few extra steps.

Baking the CakePHP model was straightforward. Just use the -c option to set the proper connection.

With those in place I could bake the FixtureFactory as normal.

Final edits

The cake bake files end up in the normal App\Model\Table and App\Model\Entity directories but my IDE makes it easy to move these to my desired location. The Factory bakes to its normal correct location.

Once I made sure the edits to the classes I’ve identified were correct, everything worked as I wanted.

What I’ve seen is that for plugin development, you move the app inside the tests folders (updating the app configs paths) and just run migrations for the app and for the plugin in the tests

See cakephp-fixture-factories example
TestApp folder
test bootstrap file

Yep, that’s the kind of thing I was hoping for. Thanks