PhpStorm,PHPUnit和setcookie

时间:2011-03-29 09:39:26

标签: php phpunit phpstorm

我正在尝试使用一个非常好的IDE PhpStorm中的setcookie()函数进行一些单元测试。但我每次都会收到以下错误:

Cannot modify header information - headers already sent by (output started at /tmp/phpunit.php:418)

这个错误的原因可能是在setcookie()调用之前使用flush()打印('some text')。但是,刷新是在PhpStorm生成的/tmp/phpunit.php文件中执行的。虽然从我的来源调用了setcookie()。所以我无法编辑生成的文件来进行某种输出缓冲。还有一些时刻:PhpStorm像这样执行/tmp/phpunit.php脚本:

/usr/bin/php /tmp/phpunit.php -config /var/www/.../protected/tests/phpunit.xml d /var/www/.../protected/tests/unit/user

请帮我解决此问题。如何直接从PhpStorm运行单元测试?

4 个答案:

答案 0 :(得分:6)

解决此问题的一种可能方法是使用{mock}替换setcookie()函数。

这是单元测试中的常用技术,您希望测试依赖于您不希望影响当前测试的外部类或函数的内容。

执行此操作的方法是在单元测试代码中为setcookie()创建存根函数定义。然后在测试期间调用它而不是真正的setcookie()函数。具体如何实现此存根函数取决于您,并取决于您的代码使用它的目的。

这种方法的主要问题是PHP默认情况下不允许您覆盖现有函数 - 如果您在标准PHP安装上尝试此操作,则会出现“错误:函数无法重新声明”

此问题的解决方案是PHP的Runkit extension,它是为此类测试明确设计的,并允许您rename an existing function,包括内置的。{/ p>

如果在测试环境中配置PHP安装以包含Runkit扩展,则可以进行此类测试。

希望有所帮助。

答案 1 :(得分:3)

我找到了一个更简单的解决方案。考虑这个课程:

class Cookie
{
    public function set($name, $value)
    {
        return setcookie($name, $value);
    }
}

除非您设置注释@runInSeparateProcess

,否则测试将抛出问题中描述的错误
class CookieTest
{
    /**
     * @runInSeparateProcess
     */
    function test_set()
    {
        $cookie = new Cookie;
        $this->assertTrue($cookie->set('mycookie', 'myvalue');
    }
}

答案 2 :(得分:0)

而不是尝试设置实际的cookie标头(由于内容已经发送而将失败);出于测试目的,您可以简单地显式设置COOKIE超全局变量:

$_COOKIE['mycookie']=myvalue';

答案 3 :(得分:0)

另一种解决方法,无需创建代理类并对其进行模拟,但需要在工作代码级别进行更改。

function setTestableCookie(string $key, $value): void
{
    $_COOKIE[$key] = $value;

    if (headers_sent() === false) {
        setcookie(
          $key,
          $value,
          ... other cookie params ...
        );
    }
}

这样,它将在单元测试中工作,并在生产代码上设置适当的cookie参数。