PHPUnit - Testing Cookies and Sessions

Hi

As you know that cookies and sessions does not work on command line, so when testing cases with phpunit how do you test functionality that uses cookies and sessions?

Thanks in advance for any help

Instead of using _COOKIE and _SESSION directly, you create objects with methods like Session::get('some_var');. Then when it runs on the website you access $_SESSION, but when run for tests you use a simple array. Ideally you would make different adapters for the different environments.

As a very basic example:


class Session
{
    private $adapter;
    public static function init(SessionAdapter $adapter)
    {
        self::$adapter = $adapter;
    }
    public static function get($var)
    {
        return self::$adapter->get($var);
    }
    public static function set($var, $value)
    {
        return self::$adapter->set($var, $value);
    }
}

interface SessionAdapter
{
    public function get($var);
    public function set($var, $value);
}

public class PhpSessionAdapter implements SessionAdapter
{
    public function get($var)
    {
        return isset($_SESSION[$var]) ? $_SESSION[$var] : null;
    }
    public function set($var, $value)
    {
        $_SESSION[$var] = $value;
    }
}

public class MemorySessionAdapter implements SessionAdapter
{
    private $session = array();
    public function get($var)
    {
        return isset($this->session[$var]) ? $this->session[$var] : null;
    }
    public function set($var, $value)
    {
        $this->session[$var] = $value;
    }
}

Then in your code for the website you start with Session::init(new PhpSessionAdapter());, and for testing you use Session::init(new MemorySessionAdapter());. Then in the rest of the code just use Session::get and Session::set without worrying the data actually goes / comes from.

Hi

Sorry for the late reply. The problem here is that I cannot change the main code, I am just allowed to test the code using phpunit. Do we have an alternate solution to this without altering main code?

Thanks

I personally don’t like the use of statics, I though it was a bad practice in OO programming. Any reason of using them in that example?

Thank you.

I suppose you could just populate the arrays $_SESSION, $_COOKIES, etc as needed.

This is one of the ways you can use to build a registry. The most heard argument against statics is that you can’t test them, but that’s not really the case here since this registry is meant to be used to swap out different adapters so you can use one adapter in production and another for testing.
Some would use DI for that, I currently use a registry for that stuff. To each their own I suppose :smiley:

Regarding that, I don’t know if it would make more sense to use the Proxy pattern instead of the Adapter that seems you have used here. Is just an opinion, I am happy to discuss it to see if I’m wrong, but it doesn’t look like you need adapting a result to a different format. Instead, you are saving a value using a data container or another, adapting the behaviour, which looks exactly like the Proxy Pattern behaves.

Indeed, Proxy Pattern would be a more apt name here. I’m using the lithium framework (li3) and they call them adapters, hence the confusion. My bad :smiley: