20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

header() 関数を使ったメソッドを PHPUnit でテストする方法

header() 関数はその実行前に何らかの標準出力がされていると「Cannot modify header information」というエラーを吐いてしまいます。
PHPUnit はテスト中のメッセージを標準出力に逐一吐き出すため、そのままでは header() 関数を用いたメソッドのテストができません。

現象

たとえば下記のようなテストケースはエラーで止まります。

class Api {
    public function output($data, $response_code = 200) {
        http_response_code($response_code);
        header('Content-Type: application/json'); // この行の前に PHPUnit が標準出力にテスト進捗を逐次出力するせいで、エラーになる
        $output = json_encode($data);

        echo $output;
        return $output;
    }
}

class ApiTest extends \PHPUnit_Framework_TestCase {
    /*
     * @covers Api::output
     */
    public function testOutput() {
        $data = ['foo' => 'bar'];
        $response_code = 200;

        ob_start();

        $actual = $this->Api->output($data, $response_code);
        $output = ob_get_contents();
        $expected = json_encode($data);

        $this->assertEquals($expected, $actual);
        $this->assertEquals($output, $actual);
        $this->assertEquals(http_response_code(), $response_code);

        ob_clean();
    }
}

上のテストを実行すると、以下のようなエラーを吐きます。

Cannot modify header information - headers already sent by (output started at C:\xampp\php\pear\PHPUnit\Util\Printer.php:172)

対策

PHPUnit の @runInSeparateProcess アノテーションを利用することで、テストケースだけを別プロセスで実行することができます。
つまり、header() 関数を使うテストだけは標準出力が真っさらなプロセスでテストできるので、エラーを吐きません。

    /**
     * @covers Api::output
     * @runInSeparateProcess
     */
    public function testOutput() {
        // ...
    }
PHPUnit 3.7.8 by Sebastian Bergmann.

.

Time: 3 seconds, Memory: 2.75Mb

OK (1 test, 3 assertions)

header() 関数を使ったメソッドのテストをする際には覚えておきたいテクニックです。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
20
Help us understand the problem. What are the problem?