Using Cookies with PHPUnit and Symfony Basic Client


Introduction

I was writing and running some simple PHPUnit functional tests using the Symfony basic client (as described here), and after authenticating (submitting a form), I noticed the client didn’t have any cookies set; or at least it appears that way. Then later after a lot of struggling, I realized that it is just a simple crawler (simple browser) and that I needed to set the cookies on my test code side. This article tells you what I did.

Creating a Client and Getting a Response

To create a client in a class that extends WebTestCase, you simply call this code:

$client = static::createClient();

This creates a client, and then you can do various things with the client. For example, on the local machine you might want to get the homepage (in this case “/”) like so:

$client->request('GET', '/');

This works fine, except for one key point: I my case, the Symfony controller (actually the twig file) was expecting certain cookies to be set in order to know that the user had already authenticated. With cookies set, then the response returned by the controller would contain different content. In my application it is where a student has filled in a form and then a cookie gets stored in the browser, the browser then maintains the cookie.

Using the Symfony client using the above 2 commands would not return the expected content, since the cookies need to first be set.

Setting Cookies

To set a cookie, we first need to get a CookieJar (holds cookies), also make sure you keep the CookieJar away from the Cookie Monster. We get the CookieJar from the client like so:

$client->getCookieJar();

The CookieJar has a set method, where we can pass in a cookie. We can combine this with the above and issue a command like so:

$client->getCookieJar()->set( $cookie );

Where in the above line, $cookie is a Cookie object.

Final Running Code

My final code looks like the following:

<?php
// tests/AppBundle/Functional/DefaultControllerTest.php
namespace tests\AppBundle\Functional;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;

class DefaultControllerTest extends WebTestCase
{
   ...
   public function testWithCookies(){
      $client = static::createClient();
      $client->getCookieJar()->set( new Cookie('form_complete', '1', strtotime('+1 day')) );
      $client->getCookieJar()->set( new Cookie('consent_complete', '1', strtotime('+1 day')) );

      $client->request('GET', '/');

      $this->assertContains(
            'Consent for Release of',
            $client->getResponse()->getContent()
      );
   }
}

In the above notice the use statement for the Cookie (you need that), and also I’ve combined setting the cookie with the getCookieJar->set() method. Then after I perform my PHPUnit assertion of the expected content.

Hoepfully this helps you, as I struggle for a while on this.

Advertisements

About Alvin Bunk
Hi, I'm a software developer at Taft College.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: