I have a simple DefaultController as service, where the DI is autowired.
class DefaultController extends BaseController
{
private $logger;
private $recordRepository;
public function __construct(LoggerInterface $logger, RecordRepository $recordRepository)
{
$this->logger = $logger;
$this->recordRepository = $recordRepository;
}
public function downloadAction($uuid)
{
$recordRepo = $this->recordRepository;
$record = $recordRepo->findActive($uuid);
$logger = $this->logger;
if (!$record) {
$logger->error('Record not found: '.$uuid);
return $this->render('default/download_error.html.twig', [
'error' => 'record_not_found'
]);
}
}
}
I've written a unit test that tries to call this method while also replacing one of the services (the logger) with a mock:
<?php
namespace Tests\AppBundle\Controller;
use Monolog\Logger;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DefaultControllerTest extends WebTestCase {
public function testDownloadAction()
{
$mock = $this->getMockBuilder(Logger::class)
->disableOriginalConstructor()
->getMock();
$mock->expects($this->once())->method('error')
->with('Record not found: 1223');
$client = static::createClient([]);
$client->getContainer()->set('logger', $mock);
$client->request('GET', '/download/12233');
print $client->getResponse()->getContent();
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
}
The problem is, when this test fails (because the logger error and expected string dont match up), the PHPunit message is put in the $client->getResponse
output instead of being caught in the CLI.
Output CLI:
PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
F<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title> Expectation failed for method name is equal to <string:error> when invoked 1 time(s) Parameter 0 for invocation Monolog\Logger::error('Record not found: 12233', Array ()) does not match expected value. Failed asserting that two strings are equal. (500 Internal Server Error) </title>
(further long webpage output removed here)
PHPUnit message:
There was 1 failure:
1) Tests\AppBundle\Controller\DefaultControllerTest::testDownloadAction
Failed asserting that 500 matches expected 200.
Do I have to use a regular PHPUnit case if I want to use mock objects? In that case I should probably refactor the $this->render
in the Controller as well.