Skyenar
Skyenar

Reputation: 39

Mocking Symfony Entities for Unit Testing using PHPUnit and Mockery

public function reportsToBeRun()
{
    $reports = $this->repository->getReportsToBeRun();

    foreach ($reports as $report) {
        $report->setUpdated(new \DateTime());
    }

    return $reports;
}

I am learning test driven development in my new job and I am struggling with how I would test the above example. I make a call to a repository that uses getResults() and returns an array of entity objects. I can mock the repository fine, but I do not know what I am best to return here. I can mock the entities and return them, but then the setUpdated will not do anything. I can obviously mock setUpdated, but I do not know how to get it to update the mocked entity or entities.

My 2nd issue with this is the tests I am writing are not really testing anything. The repository call is being mocked and so is the setter. I am then just returning whatever I mocked. What would you recommend doing for a function like this.

Upvotes: 4

Views: 4595

Answers (1)

jgxvx
jgxvx

Reputation: 352

I wouldn't mock the entities, as they are plain old PHP objects that won't access external resources.

It's better to mock the repository and have it return a collection of entities:

class MyTest extends \PHPUnit_Framework_TestCase
{

    private $service;

    protected function setUp()
    {
        parent::setUp();
        $this->service = new ReportService($this->createRepositoryMock());
    }

    protected function tearDown()
    {
        $this->service = null;
        parent::tearDown();
    }

    public function testReportsToBeRun()
    {
        $reports = $this->service->reportsToBeRun();
        $now = new \DateTime();

        foreach ($reports as $report) {
            $this->assertInstanceOf(Report::class, $report);
            $this->assertTrue($report->getUpdated() <= $now);
        }
    }

    private function createRepositoryMock()
    {
        $mock = \Mockery::mock(ReportRepository::class);

        $reports = [
            $this->createReport(1),
            $this->createReport(2),
            $this->createReport(3),
        ];

        $mock->shouldReceive('getReportsToBeRun')->andReturn($reports);
    }

    private function createReport($id)
    {
        $report = new Report();
        $report->setId($id);

        return $report;
    }
}
  • ReportService is your service that contains the reportsToBerun method.
  • Report is your entity class.
  • ReportRepository is the repository class that is mocked.

Upvotes: 1

Related Questions