Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I override php://input when doing unit tests

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

In the code I get data from 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.

like image 882
john ryan Avatar asked Jul 11 '10 01:07

john ryan


People also ask

Can we run single test method with PHPUnit?

You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file. You use the --verbose flag to get more information on the test status.

How is unit testing done in PHP?

Unit testing is a software testing process in which code blocks are checked to see whether the produced result matches the expectations. The units are tested by writing a unique test case. The unit test is generally automatic but could be implemented manually.

How to mock method in PHPUnit?

PHPUnit provides methods that are used to automatically create objects that will replace the original object in our test. createMock($type) and getMockBuilder($type) methods are used to create mock object. The createMock method immediately returns a mock object of the specified type.


2 Answers

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.

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());
like image 76
MitMaro Avatar answered Oct 09 '22 23:10

MitMaro


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'));
like image 42
Michael Dowling Avatar answered Oct 09 '22 23:10

Michael Dowling