PhpStorm,PHPUnit和setcookie

ale*_*etr 5 php phpunit phpstorm

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

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

可能出现此错误的原因是在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
Run Code Online (Sandbox Code Playgroud)

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

Spu*_*ley 6

解决此问题的一种可能方法是使用setcookie()函数的"模拟"替换.

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

这样做的方法是setcookie()在单元测试代码中创建存根函数定义.然后在测试期间调用它而不是实际setcookie()函数.具体如何实现此存根函数取决于您,并取决于您的代码使用它的内容.

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

这个问题的解决方案是PHP的Runkit扩展,它是为这种测试明确设计的,允许您重命名现有函数,包括内置函数.

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

希望有所帮助.

  • 如果您不想或不能使用RunKit(即使可以),我建议创建一个封装所有cookie操作的类.然后,您可以为该类创建一个模拟对象,以避免完全调用`setcookie()`. (6认同)

Joh*_*art 6

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

class Cookie
{
    public function set($name, $value)
    {
        return setcookie($name, $value);
    }
}
Run Code Online (Sandbox Code Playgroud)

除非您设置注释@runInSeparateProcess,否则测试将抛出问题中描述的错误

class CookieTest
{
    /**
     * @runInSeparateProcess
     */
    function test_set()
    {
        $cookie = new Cookie;
        $this->assertTrue($cookie->set('mycookie', 'myvalue');
    }
}
Run Code Online (Sandbox Code Playgroud)