6

The default practice for unit testing functionality that relies on session/cookie information is to use an abstraction library. But what if I want to write and unit test this abstraction library? The documentation for the PHP setcookiefunction says that the cookie will be available on the next request. Using a command line tool for testing, there is no such thing as a "request". So how can I unit test the correct cookie settings?

I want to test if all the parameters of the setcookie function are set correctly by my abstraction library. Those parameters will be set according to certain conditions and method calls.

The only solution I can think of is to mock the setcookie function with the runkit extension, which I don't want to install. Other ideas?

chiborg
  • 26,978
  • 14
  • 97
  • 115
  • possible duplicate of [PHPUnit - Unit Testing with items that need to send headers](http://stackoverflow.com/q/190292/) – outis Sep 24 '12 at 20:26
  • So the answers are.. a) use a wrapper and forget about unit testing that, or b) don't use it. Great. #frustrated – Erwin Wessels Feb 03 '15 at 07:41

2 Answers2

12

I found another, very simple solution: A class wrapper around the PHP setcookie function that is so simple, it does not need to be unit tested:

/**
 * Wrapper around setcookie function for better testability
 */ 
class Cookiesetter {
  public function setcookie($name, $value = "",  $expire = 0,  $path = "", 
    $domain = "", $secure = false, $httponly = false) {
    return setcookie($name, $value,  $expire, $path, $domain, $secure, $httponly);
  }
}

The setcookie method can then be mocked. This has the additional benefit that I can implement other methods like expireCookie.

chiborg
  • 26,978
  • 14
  • 97
  • 115
  • +1 This is exactly the way to do things - remove the dependencies using mocks and stubs so you can test in isolation. – Fenton Aug 29 '11 at 16:32
  • I don't understand how to test the value in `$_COOKIE['...']` with this wrapper class? – vee Jun 30 '19 at 05:30
3

You can set a value directly into the current $_COOKIE array:

<?php
$_COOKIE['test']='hello';
print_r($_COOKIE);
run_tests();

(this works in CLI mode too). Note that $_REQUEST will not be updated by this.

However if you're only trying to manipulate cookies so you can subsequently access the session, why not just access the session directly:

<?php
$_SESSION['auth_user']='root';
run_tests();

But we're talking about unit testing here - not integration testing - which suggests that the code is not very well structured.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • I can set $_COOKIE directly when I want to test behaviors that depend on values in $_COOKIE. But I also wanted to test if the other cookie parameters like expiry time and the http-only flag are set correctly by my library. – chiborg Dec 21 '10 at 14:07
  • But thanks for the comment on unit vs integration testing - There should be no need to simulate multiple requests in a unit Test. Some tests for sending the correct data and some test for the processing of the received data are better style in unit tests. So my original intent to simulate requests is unnecessary. – chiborg Dec 21 '10 at 14:10