jbelien
September 19, 2018, 12:20pm
1
Hello everyone,
I’m rather new to unit testing (better late than never ^^) and I started using PHPUnit based on Zend Expressive skeleton .
I analyzed the 3 available tests and understood how it works.
But my application uses Zend\Expressive\Session\SessionMiddleware
so, obviously, the test brakes.
Here is my handler :
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
if (!$session->has('tempDirectory')) {
$session->set('tempDirectory', 'data/temp/'.uniqid());
}
$data = [];
return new HtmlResponse($this->template->render('app::home-page', $data));
}
Here is the “error” returned by PHPUnit :
1) AppTest\Handler\HomePageHandlerTest::testReturnsHtmlResponseWhenTemplateRendererProvided
Error: Call to a member function has() on null
I get that during the test the session is not initialized and so PHPUnit can’t use getAttribute(SessionMiddleware::SESSION_ATTRIBUTE)
but how can/should I fix this ?
Thanks a lot !
How does your test look like? Usually you’d mock ServerRequestInterface
with tools like prophecy to provide a specific state https://phpunit.de/manual/6.5/en/test-doubles.html#test-doubles.prophecy
jbelien
September 20, 2018, 12:42pm
3
Thanks @tux-rampage ;
As I mentioned, so for I play with Zend Expressive Skeleton tests : https://github.com/zendframework/zend-expressive-skeleton/blob/master/test/AppTest/Handler/HomePageHandlerTest.php
I already had a look at prophecy documentation but I don’t get how I can “setup” the session in the test.
jbelien
September 20, 2018, 2:55pm
5
Should have thought about that …
Thanks a lot, I’ll have a look !
jbelien
September 21, 2018, 8:50am
6
Considering my handler :
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
if (!$session->has('tempDirectory')) {
$session->set('tempDirectory', 'data/temp/'.uniqid());
}
$data = [];
return new HtmlResponse($this->template->render('app::home-page', $data));
}
I made this test :
class HomePageHandlerTest extends TestCase
{
/** @var ContainerInterface|ObjectProphecy */
protected $container;
/** @var TemplateRendererInterface|ObjectProphecy */
protected $renderer;
/** @var RouterInterface|ObjectProphecy */
protected $router;
/** @var SessionInterface|ObjectProphecy */
protected $session;
protected function setUp()
{
$this->container = $this->prophesize(ContainerInterface::class);
$this->renderer = $this->prophesize(TemplateRendererInterface::class);
$this->router = $this->prophesize(RouterInterface::class);
$this->session = $this->prophesize(SessionInterface::class);
}
public function testReturnsHtmlResponse()
{
$this->session
->has('tempDirectory')
->willReturn(true);
$this->renderer
->render('app::home-page', Argument::type('array'))
->willReturn('');
$homePage = new UploadHandler(
$this->router->reveal(),
$this->renderer->reveal(),
get_class($this->container->reveal())
);
$request = $this->prophesize(ServerRequestInterface::class);
$request
->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE)
->willReturn($this->session);
$response = $homePage->handle(
$request->reveal()
);
$this->assertInstanceOf(HtmlResponse::class, $response);
}
}
Does it make sense ?
Did I cover “everything” ?
Can it be improved ?
Thanks again for all your help