# Unit testing with session

**URL:** <https://discourse.laminas.dev/t/unit-testing-with-session/742>\
**Category:** Mezzio\
**Tags:** expressive, session, phpunit\
**Created:** [September 19, 2018, 12:20pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742 "2018-09-19T12:20:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbelien](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/jbelien/32/251_2.png) [@jbelien](https://discourse.laminas.dev/u/jbelien)\
**Post date:** [September 19, 2018, 12:20pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/1 "2018-09-19T12:20:35Z")

</div>

Hello everyone,

I’m rather new to unit testing (better late than never ^^) and I started using PHPUnit based on [Zend Expressive skeleton](https://github.com/zendframework/zend-expressive-skeleton).

I analyzed the [3 available tests](https://github.com/zendframework/zend-expressive-skeleton/tree/master/test/AppTest/Handler) and understood how it works.

But my application uses `Zend\Expressive\Session\SessionMiddleware` so, obviously, the test brakes.

Here is my handler :

```php
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 :

```bash
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 !

---

<div class="post-metadata">

**Author:** ![tux-rampage](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/tux-rampage/32/237_2.png) [@tux-rampage](https://discourse.laminas.dev/u/tux-rampage)\
**Post date:** [September 19, 2018, 5:14pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/2 "2018-09-19T17:14:32Z")

</div>

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](https://phpunit.de/manual/6.5/en/test-doubles.html#test-doubles.prophecy)

---

<div class="post-metadata">

**Author:** ![jbelien](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/jbelien/32/251_2.png) [@jbelien](https://discourse.laminas.dev/u/jbelien)\
**Post date:** [September 20, 2018, 12:42pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/3 "2018-09-20T12:42:40Z")

</div>

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](https://github.com/zendframework/zend-expressive-skeleton/blob/master/test/AppTest/Handler/HomePageHandlerTest.php)

I already had a look at [prophecy documentation](https://phpunit.de/manual/6.5/en/test-doubles.html#test-doubles.prophecy) but I don’t get how I can “setup” the session in the test.

---

<div class="post-metadata">

**Author:** ![xtreamwayz](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/xtreamwayz/32/27_2.png) [@xtreamwayz](https://discourse.laminas.dev/u/xtreamwayz)\
**Post date:** [September 20, 2018, 2:22pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/4 "2018-09-20T14:22:31Z")

</div>

Take a look at the zend-expression-session tests. It should get you in the right direction: [https://github.com/zendframework/zend-expressive-session/blob/master/test/SessionMiddlewareTest.php](https://github.com/zendframework/zend-expressive-session/blob/master/test/SessionMiddlewareTest.php)

---

<div class="post-metadata">

**Author:** ![jbelien](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/jbelien/32/251_2.png) [@jbelien](https://discourse.laminas.dev/u/jbelien)\
**Post date:** [September 20, 2018, 2:55pm UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/5 "2018-09-20T14:55:45Z")

</div>

Should have thought about that …

Thanks a lot, I’ll have a look !

---

<div class="post-metadata">

**Author:** ![jbelien](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/jbelien/32/251_2.png) [@jbelien](https://discourse.laminas.dev/u/jbelien)\
**Post date:** [September 21, 2018, 8:50am UTC](https://discourse.laminas.dev/t/unit-testing-with-session/742/6 "2018-09-21T08:50:06Z")

</div>

Considering my handler :

```php
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 :

```php
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 🙂
