0
votes

A coworker wants to mock the entity manager in a test. He has this code:

    ...
    $em = $this->createMock(EntityManager::class);
    $myRepository = new NewslettersStatisticSnapshotRepository(
        $em,
        NewslettersStatisticSnapshot::class
    );

    $em->method('getRepository')->willReturn($myRepository);
    ...

... and when I run his test, I get this:

TypeError: Argument 2 passed to Doctrine\ORM\EntityRepository::__construct() must be an instance of Doctrine\ORM\Mapping\ClassMetadata, string given

How can I dig up metadata for this class?

2
You have something else going on. Internally the entity manager creates repositories for many reasons and they don't always go through getRepository. You need to mock all the manager methods being used by the code being tested. Which could be challenging. - Cerad
@Cerad I believe it's a question of coding rules. If the (to be tested!) code always runs getRepository and use those repositories returned, then this approach is absolutely reasonable. - Jakumi
@Jakumi - Sure but the error message shows that it does not. Clearly something is trying to create/access a repository without going through getRepo. Actually, upon rereading the question, the answer is even simpler. He is trying to create an actual repository by passing entity class name instead of metadata. The repository itself needs to be mocked since you really cannot create repositories directly. - Cerad
@Cerad I assume NewslettersStatisticSnapshotRepository::__construct calls its parent class' constructor (EntityRepository::__construct) - or the constructor isn't even implemented in the "custom" repository. anyway, the second parameter really is a string, and the second parameter should be ClassMetadata. so that's the error message happening right there and nowhere else. - Jakumi
Patrick, what is the code supposed to test? the repository? if so, this would be the better approach: symfony.com/doc/current/testing/doctrine.html (just prepare entity manager and check what changed). if you want to test something, that uses the repository, it should depend on that repository, and not on the EntityManager IMHO. - Jakumi

2 Answers

3
votes

You can do it in following way:

 $em                 = $this->getDoctrine()->getManager();
 $metadata           = $em->getClassMetadata(NewslettersStatisticSnapshot::class);
0
votes

We ended up just mocking the repository.