简体   繁体   English

Symfony / Phpunit - 如何测试 Doctrine 标准(或表达式)

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

I'm looking for a way to make assertions on the definition of a Criteria in a unit-test (with Phpunit).我正在寻找一种方法来对单元测试中的标准定义做出断言(使用 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.我找不到任何方法允许访问标准 object 的定义,因此我无法断言任何内容。

I'm currently writing unit-tests for a method that creates a Criteria and passes it to a repo:我目前正在为创建 Criteria 并将其传递给 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:在我的测试中,我模拟了存储库,并添加了对“匹配”方法的调用的期望,并使用 Criteria 作为唯一参数:

$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.我尝试使用$c->getWhereExpression()获取表达式的条件,但也没有找到任何测试方法。

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.我想使用 EntityManager 来创建一个 Query 并检索它的 SQL,但是依赖注入不适用于测试,而且我找到的解决方案似乎有点太重了。 If possible, I'd prefer not having to boot a kernel and instantiate the EntityManager to test a simple Criteria.如果可能的话,我宁愿不必启动 kernel 并实例化 EntityManager 来测试一个简单的标准。

I'm using:我在用着:

  • Symfony 5.4 Symfony 5.4
  • Doctrine 2.9 Doctrine 2.9
  • Php 8.0 Php 8.0

Thanks to @dbrumann, I managed to solve this by applying the Criteria directly on a Collection, and by testing the result.感谢@dbrumann,我设法通过直接在集合上应用标准并测试结果来解决这个问题。 Here is an example with a simplified criteria that would filter temporary files:这是一个带有简化标准的示例,可以过滤临时文件:

$file1 = $this->getMockBuilder(File::class)->getMock();
$file1->method('getIsTemporaryFile')->willReturn(false);

$file2 = $this->getMockBuilder(File::class)->getMock();
$file1->method('getIsTemporaryFile')->willReturn(true);

$files = new ArrayCollection([$file1, $file2]);

$this->fileRepository
        ->expects(self::once())
        ->method('matching')
        ->with(
            self::callback(static function (Criteria $c) use ($files) {
                $matching = $files->matching($c)->toArray();
                return count($matching) === 1 && array_values($matching)[0] === $files[1];
            })
        )->willReturn($files);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM