I've been tasked with writing unit tests for legacy code. My current test is on an object that takes the Doctrine 2 entity manager as a constructor parameter. I need to be able to feed it test data so I can reliably test its methods.
So, ideally, I'd like to be able to create a mock entity manager, then create a mock entity and attach it to the mock entity manager, and then use that in my tests. Is this possible? If so, how?
This project is using Symfony 2.4+, so I'm pretty sure that adds a wrinkle or two in the setup.
Not sure if this will apply or not to your specific needs in Symfony (full stack?) setup, but on previous projects where we were using Symfony Components (and Doctrine), but not the full-stack, this was more or less the setup followed:
<?php
namespace Tests\SomeNameSpace;
use Doctrine\ORM\EntityRepository;
use SomeNameSpace\Repositories\SomeRepository;
use SomeNameSpace\SubjectUnderTesting;
class SubjectUnderTestingTest extends \PHPUnit_Framework_TestCase
{
public function testSomething()
{
$queryExpectedValue = 'define expected return from query';
/**
* Infering that the the Subject Under Test is dealing with a single
* repository.
*
* @var Doctrine\ORM\EntityRepository
*/
$repository = $this
->getMockBuilder('Doctrine\ORM\EntityRepository')
->disableOriginalConstructor()
->setMethods(array('findOneByEmail'))
->getMock();
$repository
->expects($this->once())
->method('findOneByEmail')
->will($this->returnValue($queryExpectedValue));
/**
* Now mock the EntityManager that will return the aforementioned
* Repository. Extend to more repositories with a returnValueMap or
* with clauses in case you need to handle more than one repository.
*
* @var Doctrine\ORM\EntityManager
*/
$entityManager = $this
->getMockBuilder('Doctrine\ORM\EntityManager')
->setMethods(array('getRepository'))
->disableOriginalConstructor()
->getMock();
$entityManager
->expects($this->once())
->method('getRepository')
->with('SomeNameSpace\Repositories\SomeRepository')
->will($this->returnValue($repository));
/**
* Let's instantiate our Subject Under Test passing the mock as
* required.
*
* This code above is tailored to a scenario where the SUT method
* being tested will call something like this in the method to test:
*
* $queryResult = $entityManager
* ->getRepository('SomeNameSpace\Repositories\SomeRepository')
* ->findOneByEmail($someEmail);
*
* @var SubjectUnderTesting
*/
$sut = new SubjectUnderTesting($entityManager);
/**
* Assertions time if they apply.
*/
$expected = 'define what to expect';
$this->assertEquals(
$expected,
$sut->callSomeMethodToTestThatDependsOnSomeQueryByEmail()
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With