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