如何在 Symfony 中为使用 queryBuilder 构建的 MongoDB 查询编写单元测试
How to write a unit test for MongoDB query built with queryBuilder in Symfony
我正在努力理解如何为这段代码编写单元测试
$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单位:PHP单位8.5.21
PHP: PHP 7.2.34
Symfony:Symfony 4.4.18
错误出现是因为你没有从$documentManager
开始模拟,你的测试用例显然必须从它开始。
我曾经使用 Prophecy
进行测试,但使用原生 MockBuilder
时逻辑相同。
考虑到我不知道真实的 class 你的用例正在使用,所以我让你大致了解你必须做什么,看看下面的代码:
$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();
这是我修复它的方法。这可能对遇到类似问题的人有帮助
$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);
我正在努力理解如何为这段代码编写单元测试
$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单位:PHP单位8.5.21
PHP: PHP 7.2.34
Symfony:Symfony 4.4.18
错误出现是因为你没有从$documentManager
开始模拟,你的测试用例显然必须从它开始。
我曾经使用 Prophecy
进行测试,但使用原生 MockBuilder
时逻辑相同。
考虑到我不知道真实的 class 你的用例正在使用,所以我让你大致了解你必须做什么,看看下面的代码:
$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();
这是我修复它的方法。这可能对遇到类似问题的人有帮助
$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);