Home > OS >  How to write a unit test for MongoDB query built with queryBuilder in Symfony
How to write a unit test for MongoDB query built with queryBuilder in Symfony

Time:12-15

I am struggling to understand how to write unit test for this piece of code

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

Here is my attempt to mock this part

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

but I keep getting this error when the control reaches this part. enter image description here

Thank you in advance.

PHP unit: PHPUnit 8.5.21

PHP: PHP 7.2.34

Symfony: Symfony 4.4.18

CodePudding user response:

The error appears because you don't mock from $documentManager, your test case must start from it apparently.

I used to test with Prophecy but with native MockBuilder it's same logic. Consider I don't know real class your use case is using so I give you an idea of approximately what you have to do, take a look at code below:

    $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')
    ;

We exactly mock each call of original code

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

CodePudding user response:

Here is how I fixed it,. it might be helpful to someone struggling with similar issue

$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);
  • Related