【问题标题】:How to write a unit test for MongoDB query built with queryBuilder in Symfony如何在 Symfony 中为使用 queryBuilder 构建的 MongoDB 查询编写单元测试
【发布时间】:2022-01-16 01:36:04
【问题描述】:

我很难理解如何为这段代码编写单元测试

$qb = $documentManager->getRepository('Document:Account')->createQueryBuilder();
$qb->remove(\project\Document\Account::class)->field('username')
   ->equals($userAccount->getUsername())->getQuery()->execute();

这是我模拟这部分的尝试

$account = new account();
$documentAccount = $this->createMock(documentAccount::class);
$this->dm->expects($this->any())->method('getRepository')
     ->with($documentAccount)
     ->willReturn($account);

但当控件到达此部分时,我不断收到此错误。

提前谢谢你。

PHP 单元:PHPUnit 8.5.21

PHP:PHP 7.2.34

Symfony:Symfony 4.4.18

【问题讨论】:

    标签: php symfony phpunit


    【解决方案1】:

    出现错误是因为你没有从$documentManager模拟,你的测试用例显然必须从它开始。

    我曾经使用Prophecy 进行测试,但使用原生MockBuilder 是相同的逻辑。 考虑到我不知道你的用例使用的真实类,所以我让你大致了解你必须做什么,看看下面的代码:

        $queryBuilder = $this->createMock(QueryBuilder::class);
        $documentManager = $this->createMock(DocumentMannager::class);
        $documentAccount = $this->createMock(Document::Account);
        
        $documentManager
            ->expects($this->once())
            ->method('getRepository')
            ->with('Document:Account')
            ->willReturn($documentAccount)
        ;
    
        $documentAccount
            ->expects($this->once())
            ->method('createQueryBuilder')
            ->willReturn($queryBuilder)
        ;
        
        $queryBuilder
            ->expects($this->once())
            ->method('remove')
            ->with(\project\Document\Account::class)
            ->willReturn($queryBuilder)
        ;
        
        $queryBuilder
            ->expects($this->once())
            ->method('field')
            ->with('username')
            ->willReturn($queryBuilder)
        ;
        
        $queryBuilder
            ->expects($this->once())
            ->method('equals')
            ->withAnyParameters()
            ->willReturn($queryBuilder)
        ;
        
        $queryBuilder
            ->expects($this->once())
            ->method('getQuery')
            ->willReturn($queryBuilder)
        ;
        
        
        $queryBuilder
            ->expects($this->once())
            ->method('execute')
        ;
    

    我们精确地模拟原始代码的每次调用

    $qb = $documentManager->getRepository('Document:Account')->createQueryBuilder();
    $qb->remove(\project\Document\Account::class)->field('username')
       ->equals($userAccount->getUsername())->getQuery()->execute();
    

    【讨论】:

    • 对不起,我忘了提到$documentManager 已通过测试为$this->dm
    • 您在声明后没有在任何地方使用$documentManager。其次,您的意思是 $queryBuilder = $this->createMock(documentAccount::class); 吗?当你说$queryBuilder = $this->createMock(QueryBuilder::class); documentAccount 是Document:Account 谢谢
    • 我编辑解决方案,因为我忘记了 $documentManager, 方法 ->createQueryBuilder() 的模拟,你必须检查什么是建立相应模拟的真正类,我不认为它是 documentAccount,不要不要忘记这是一个提案,因为我不知道你的全部代码。
    【解决方案2】:

    这是我修复它的方法。这可能对遇到类似问题的人有所帮助

    $accountDocumentRepo = $this->getMockBuilder(\project\Document\Account::class)
                ->disableOriginalConstructor()
                ->disableOriginalClone()
                ->disableArgumentCloning()
                ->disallowMockingUnknownTypes()
                ->setMethods(['remove','createQueryBuilder','field','equals','getQuery', 'execute'])
                ->getMock();
    
            $this->tradeDm->expects(self::any())->method('getRepository')->willReturn($accountDocumentRepo);
    
            $accountDocumentRepo->method('createQueryBuilder')->willReturn($accountDocumentRepo);
            $accountDocumentRepo->method('remove')->willReturn($accountDocumentRepo);
            $accountDocumentRepo->method('equals')->willReturn($accountDocumentRepo);
            $accountDocumentRepo->method('field')->willReturn($accountDocumentRepo);
            $accountDocumentRepo->method('getQuery')->willReturn($accountDocumentRepo);
            $accountDocumentRepo->method('execute')->willReturn($accountDocumentRepo);
    

    【讨论】:

    • 正如我在回答中提到的,您需要模拟所有调用的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2019-06-07
    • 2020-12-21
    • 1970-01-01
    • 2018-03-15
    • 2014-02-14
    • 2015-03-23
    相关资源
    最近更新 更多