Symfony / Phpunit - How to test a Doctrine Criteria (or Expression)

Viewed 38

I'm looking for a way to make assertions on the definition of a Criteria in a unit-test (with Phpunit).

I couldn't find any method allowing to access the definition of the Criteria object, thus I've got no way of asserting anything on it.

I'm currently writing unit-tests for a method that creates a Criteria and passes it to a repo :

$criteria = new Criteria();
$criteria->where(
    Criteria::expr()?->andX(
        Criteria::expr()?->eq('isTemporaryFile', 1),
        Criteria::expr()?->orX(
            Criteria::expr()?->lt('creationDate', $maxDate),
            Criteria::expr()?->isNull('creationDate')
        )
    )
);

return $this->myFileRepository->matching($criteria);

In my test, I mocked the repository and I add an expectation for a call to the 'matching' method, with a Criteria as the only parameter :

$this->fileRepository
    ->expects(self::once())
    ->method('matching')
    ->with(
        self::callback(static function (Criteria $c) {
            return $c instanceof Criteria;
        })
    )->willReturn($files);

But I can't find a way to test the criteria itself in the callback.

What I would like to do is something like this :

self::callback(static function (Criteria $c) {
    return $c instanceof Criteria &&
        $c->getSql() === 'isTemporaryFile=1 AND (creationDate<2022-01-01T12:00:00+00:00 OR creationDate IS NULL)';
})

Or something like :

self::callback(static function (Criteria $c) {
    return $c instanceof Criteria &&
        $c->getExpressions()[0]->getField() === 'isTemporaryFile' &&
        $c->getExpressions()[0]->getOp() === '=' &&
        $c->getExpressions()[0]->getValue() === '1' &&
        (...etc)
        ;
})

I tried to get the criteria where expression with $c->getWhereExpression(), but didn't find any way to test it either.

I thought to use the EntityManager to create a Query and retrieve its SQL, but dependency injection doesn't work with tests, and the solution I found seemed a little too heavy. If possible, I'd prefer not having to boot a kernel and instantiate the EntityManager to test a simple Criteria.

I'm using :

  • Symfony 5.4
  • Doctrine 2.9
  • Php 8.0
0 Answers
Related