Mocking database for unit tests queries in Modx

It’s is difficult because $modx/xPDO is the database. It might help to put the three lines that create the query in a separate method called getQuery(). That will also help you when you want to create an integration test to see if the created query looks like it should.

Once the query is moved, you can mock getQuery() (it can return null since you’re not going to use the return value). The, create a mock of the $modx object with one mock method: getCount(). You can have getCount() return whatever you like.

I use Codeception (which wraps PhpUnit and provides Acceptance testing). With Codeception, you can automate Acceptance tests that log in to the Manager, click on links and buttons, and verify the results on the screen. I mention Codeception because this mocking code will look different than PhpUnit’s, but here’s a mock $modx class I needed for a unit test:

$modx = $this->make(modX::class, array(
            'getTableName' => function () {
                return '`modx_site_content`';
            }
        ));
        assertInstanceOf('modX', $modx);

This was to test a processor of mine. The only MODX method it ever called in the methods I was testing was getTableName().

If you want to be more elaborate, you can (in theory), create an in-memory database that stores either an array of user objects just an array of rows (like the modx_users table). The, you can mock $user->save(), $modx->getObject(), etc.