如何在进行单元测试时覆盖php://输入

时间:2022-10-15 20:05:42

I'm trying to write a unit test for a controller using Zend and PHPUnit

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

In the code I get data from php://input

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

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

My code works fine when I test the real application, but unless I can supply data as a raw http post, $data will always be blank. The getRawBody() method basically calls file_get_contents('php://input'), but how do I override this in order to supply the test data to my application.

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

4 个解决方案

#1


3  

Provided the $req->getRawBody() is, as you say, the same as file_get_contents('php://input')...

假设$ req-> 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();

Not a perfect solution, but similar to what I have used in the past when designing scripts to handle piped emails with great success.

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

#2


10  

I had the same problem and the way I fixed it was to have the 'php://input' string as a variable that is settable at run time. I know this does not really apply directly to this question as it would require modifying the Zend Framework. But all the same it may be helpful to someone.

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

For example:

例如:

<?php
class Foo {

    public function read() {
        return file_get_contents('php://input');
    } 
}

would become

会成为

<?php
class Foo {

    public $_fileIn = 'php://input';

    public function read() {
        return file_get_contents($this->_fileIn);
    }

}

Then in my unit test I can do:

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

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

#3


7  

You could try mocking the object in your unit tests. Something like this:

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

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

#4


0  

Zend_Controller_Request_HttpTestCase contains methods for setting and getting various http request/responses.

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

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

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

#1


3  

Provided the $req->getRawBody() is, as you say, the same as file_get_contents('php://input')...

假设$ req-> 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();

Not a perfect solution, but similar to what I have used in the past when designing scripts to handle piped emails with great success.

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

#2


10  

I had the same problem and the way I fixed it was to have the 'php://input' string as a variable that is settable at run time. I know this does not really apply directly to this question as it would require modifying the Zend Framework. But all the same it may be helpful to someone.

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

For example:

例如:

<?php
class Foo {

    public function read() {
        return file_get_contents('php://input');
    } 
}

would become

会成为

<?php
class Foo {

    public $_fileIn = 'php://input';

    public function read() {
        return file_get_contents($this->_fileIn);
    }

}

Then in my unit test I can do:

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

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

#3


7  

You could try mocking the object in your unit tests. Something like this:

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

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

#4


0  

Zend_Controller_Request_HttpTestCase contains methods for setting and getting various http request/responses.

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

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

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