使用PHPUnit测试cookie和会话,如何?

时间:2010-06-16 01:21:37

标签: php unit-testing session cookies phpunit

使用PHPUnit,测试原始PHP代码非常容易,但是那些严重依赖于cookie的代码呢?会议可以是一个很好的例子。

有没有一种方法不需要我在测试期间设置$_COOKIE数据?这感觉就像是一种做事的黑客方式。

3 个答案:

答案 0 :(得分:6)

这是代码的常见问题,尤其是滞后的PHP代码。使用的常用技术是进一步抽象相关对象中的COOKIE / SESSION变量,并使用控制技术的反转将这些依赖项拉入范围。

http://martinfowler.com/articles/injection.html

现在,在执行测试之前,您将实例化Cookie / Session对象的模拟版本并提供默认数据。

我想,通过在执行测试之前简单地覆盖超级全局值,可以使用遗留代码实现相同的效果。

干杯, 亚历

答案 1 :(得分:2)

我知道这已经很老了,但我相信这需要随着技术自原始帖子以来的改进而更新。我能够使用php 5.4和phpunit 3.7获得使用此解决方案的会话:

class UserTest extends \PHPUnit_Framework_TestCase {
    //....
    public function __construct () {
        ob_start();
    }

    protected function setUp() {
       $this->object = new \User();
    }

    public function testUserLogin() {
       $this->object->setUsername('test');
       $this->object->setPassword('testpw');
       // sets the session within:
       $this->assertEquals(true, $this->object->login());
    }
}

答案 2 :(得分:0)

我发现我可以使用PHPUnit来测试我的网站中严重依赖会话的部分的行为,通过 Curl cookie 的组合传递会话ID

以下Curl类使用CURLOPT_COOKIE选项传递会话参数。静态变量$sessionid在不同的Curl调用之间保存会话。此外,可以使用静态函数changeSession更改会话。

class Curl {
    private $ch;
    private static $sessionid;

    public function __construct($url, $options) {
        $this->ch = curl_init($url);

        if (!self::$sessionid)
            self::$sessionid = .. generateRandomString() ..;

        $options = $options + array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_COOKIE => 'PHPSESSID=' . self::$sessionid);

        foreach ($options as $key => $val) {
            curl_setopt($this->ch, $key, $val);
        }
    }

    public function getResponse() {
        if ($this->response) {
            return $this->response;
        }

        $response = curl_exec($this->ch);
        $error    = curl_error($this->ch);
        $errno    = curl_errno($this->ch);
        $header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
        $this->header = substr($response, 0, $header_size);
        $response = substr($response, $header_size);

        if (is_resource($this->ch)) {
            curl_close($this->ch);
        }

        if (0 !== $errno) {
            throw new \RuntimeException($error, $errno);
        }

        return $this->response = $response;
    }

    public function __toString() {
        return $this->getResponse();
    }

    public static function changeSession() {
        self::$SESSIONID = Practicalia::generateRandomString();
    }
}

示例电话

$data = array(
    'action' => 'someaction',
    'info' => 'someinfo'
);

$curl = new Curl(
    'http://localhost/somephp.php', 
    array(
        CURLOPT_POSTFIELDS => http_build_query($data)));

$response = $curl->getResponse();

除非特别调用Curl::changeSession(),否则任何后续的Curl调用都将自动使用与前一个相同的会话。