当前位置:  开发笔记 > 编程语言 > 正文

使用需要发送标头的项目进行单元测试

如何解决《使用需要发送标头的项目进行单元测试》经验,为你挑选了5个好方法。

我目前正在使用PHPUnit来尝试和我正在编写的内容一起开发测试,但是,我正在编写会话管理器,并且遇到了这样的问题......

Session处理类的构造函数是

private function __construct()
{
    if (!headers_sent())
    {
        session_start();
        self::$session_id = session_id();
    }
}

但是,由于PHPUnit在开始测试之前发送文本,因此对此Object的任何测试都会返回失败的测试,因为HTTP"Headers"已经发送...



1> troelskn..:

好吧,您的会话管理器基本上是按设计破解的.为了能够测试某些东西,必须能够将其与副作用隔离开来.不幸的是,PHP被设计以这样一种方式,它鼓励自由使用全局状态(echo,header,exit,session_start等等,等等).

您可以做的最好的事情是隔离组件中的副作用,这些副作用可以在运行时交换.这样,您的测试可以使用模拟对象,而实时代码使用具有真正副作用的适配器.你会发现这对单身人士来说效果不佳,我猜你正在使用它.因此,您必须使用其他一些机制来获取分配给代码的共享对象.您可以从静态注册表开始,但如果您不介意一点学习,还有更好的解决方案.

如果你不能这样做,你总是可以选择编写集成测试.例如.使用PHPUnit的等价物WebTestCase.



2> 小智..:

为phpunit创建一个bootstrap文件,调用:

session_start();

然后像这样启动phpunit:

phpunit --bootstrap pathToBootstrap.php --anotherSwitch /your/test/path/

引导文件在其他所有内容之前被调用,因此标头尚未发送,一切都应该正常工作.



3> 小智..:

phpUnit在测试运行时输出输出,因此即使在第一次测试中,headers_sent()也会返回true.

要解决整个测试套件的这个问题,您只需在设置脚本中使用ob_start()即可.

例如,假设你有一个名为AllTests.php的文件,这是phpUnit加载的第一件事.该脚本可能如下所示:

addTest(YourFramework_AllTests::suite());
        return $suite;
    }
}


测试黑盒PHP代码的最佳解决方案,你无法改变.
这个解决方案对我有用:D PHPUnit 3.6应该实现这个但是对我来说不能正常工作.我添加了ob_start(); 进入我的bootstrap.php文件,我的所有测试与cookie和标题再次开始正常工作.

4> Juanjo Laine..:

我有同样的问题,我通过使用--stderr标志调用phpunit来解决它,就像这样:

phpunit --stderr /path/to/your/test

希望它可以帮到某人!



5> Kornel..:

我认为"正确"的解决方案是创建一个非常简单的类(这么简单,不需要测试),这是PHP的会话相关函数的包装,并使用它而不是session_start()直接调用等.

在测试中传递模拟对象而不是真正有状态的,不可测试的会话类.

private function __construct(SessionWrapper $wrapper)
{
   if (!$wrapper->headers_sent())
   {
      $wrapper->session_start();
      $this->session_id = $wrapper->session_id();
   }
}

推荐阅读
爱唱歌的郭少文_
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有