【问题标题】:how do I override php://input when doing unit tests进行单元测试时如何覆盖 php://input
【发布时间】:2011-03-14 09:17:52
【问题描述】:

我正在尝试使用 Zend 和 PHPUnit 为控制器编写单元测试

在代码中我从 php://input 获取数据

$req = new Zend_Controller_Request_Http();
$data = $req->getRawBody();

当我测试真正的应用程序时,我的代码运行良好,但除非我可以将数据作为原始 http 帖子提供,否则 $data 将始终为空白。 getRawBody() 方法基本上调用 file_get_contents('php://input'),但我如何覆盖它以便将测试数据提供给我的应用程序。

【问题讨论】:

    标签: php unit-testing zend-framework phpunit


    【解决方案1】:

    我遇到了同样的问题,我修复它的方法是将'php://input' 字符串作为可在运行时设置的变量。我知道这并不真正直接适用于这个问题,因为它需要修改 Zend 框架。但尽管如此,它可能对某人有所帮助。

    例如:

    <?php
    class Foo {
    
        public function read() {
            return file_get_contents('php://input');
        } 
    }
    

    会变成

    <?php
    class Foo {
    
        public $_fileIn = 'php://input';
    
        public function read() {
            return file_get_contents($this->_fileIn);
        }
    
    }
    

    然后在我的单元测试中我可以做到:

    <?php
    $obj = new Foo();
    $obj->_fileIn = 'my_input_data.dat';
    assertTrue('foo=bar', $obj->read());
    

    【讨论】:

    • 您也可以拥有一个受保护的属性,并在测试中使用反射将其更改为公共属性。所以对于生产来说,你的代码更干净一些。 (假设 php 5.3)
    【解决方案2】:

    您可以尝试在单元测试中模拟对象。像这样的:

    $req = $this->getMock('Zend_Controller_Request_Http', array('getRawBody'));
    $req->method('getRawBody')
        ->will($this->returnValue('raw_post_data_to_return'));
    

    【讨论】:

    • 所以如果我将 Zend_Controller_Request_Http 对象传递到我正在测试的代码中,这将起作用,不幸的是控制器在后台处理了所有这些。所以我认为唯一的方法是改变我的应用程序来测试我所处的环境并处理特殊情况。
    【解决方案3】:

    前提是$req-&gt;getRawBody() 与您所说的file_get_contents('php://input') 相同...

    $test = true; /* Set to TRUE when using Unit Tests */
    
    $req = new Zend_Controller_Request_Http();
    if( $test )
      $data = file_get_contents( 'testfile.txt' );
    else
      $data = $req->getRawBody();
    

    不是一个完美的解决方案,但类似于我过去在设计脚本以处理管道电子邮件时所使用的方法并取得了巨大成功。

    【讨论】:

    • 是的,这不是一个完美的解决方案,但我也决定如何实施它。谢谢。
    • 我不推荐这个解决方案——使用if 语句在单元测试和生产环境中执行不同的代码。理想情况下,您希望您的代码在两个世界中执行相同的逻辑语句。请参阅下面的@MitMaro 解决方案,该解决方案使用可配置的输入路径。
    【解决方案4】:

    Zend_Controller_Request_HttpTestCase 包含设置和获取各种 http 请求/响应的方法。

    例如: $req = new Zend_Controller_Request_HttpTestCase; $req->setCookie('cookie', 'TRUE'); $test = $this->controller->cookieAction($req); $this->assertSame($test, TRUE);

    【讨论】:

      猜你喜欢
      • 2013-07-08
      • 1970-01-01
      • 2013-10-23
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多