はらへり日記

腹に弾丸

Laravelのアプリケーションテストでコケた

Laravelのアプリケーションテスト

LaravelでPHPUnitを使うとLaravelによる拡張でアプリケーションテストを行うことが出来る(Laravel 5.1以上)

テスト 5.1 Laravel

なので上記ドキュメントに従って以下の様な感じでテストを書いてみた。

<?php

class LoginPageTest extends TestCase
{
    public function setUp()
    {
        parent::setUp();
    }

    /**
     * ログインページヘアクセス
     * 
     * @test
     */
    public function loginPageTest()
    {
        $this->visit('/login')->see('ようこそ!');
    }
}

これでログインページにアクセスし、'ようこそ!'の文字列があるかどうかを見ることが出来る。

はずでした。

エラー

==== Redirecting to composer installed version in vendor/phpunit ====

PHP Fatal error:  Call to a member function make() on null in /usr/share/nginx/html/like_award_php/vendor/laravel/framework/src/Illuminate/Foundation/Testing/CrawlerTrait.php on line 682
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:35
PHP   3. PHPUnit_TextUI_Command->run() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/TextUI/Command.php:100
PHP   4. PHPUnit_TextUI_Command->handleArguments() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/TextUI/Command.php:110
PHP   5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/TextUI/Command.php:636
PHP   6. PHPUnit_Util_Configuration->getTestSuite() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Util/Configuration.php:860
PHP   7. PHPUnit_Framework_TestSuite->addTestFiles() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Util/Configuration.php:947
PHP   8. PHPUnit_Framework_TestSuite->addTestFile() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:403
PHP   9. PHPUnit_Framework_TestSuite->addTestSuite() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:377
PHP  10. PHPUnit_Framework_TestSuite->__construct() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:295
PHP  11. PHPUnit_Framework_TestSuite->addTestMethod() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:194
PHP  12. PHPUnit_Framework_TestSuite::createTest() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:861
PHP  13. LoginPageTest->loginPageTest() /usr/share/nginx/html/like_award_php/vendor/phpunit/phpunit/src/Framework/TestSuite.php:466
PHP  14. Illuminate\Foundation\Testing\TestCase->visit() /usr/share/nginx/html/like_award_php/tests/Integrations/LoginPageTest.php:27
PHP  15. Illuminate\Foundation\Testing\TestCase->makeRequest() /usr/share/nginx/html/like_award_php/vendor/laravel/framework/src/Illuminate/Foundation/Testing/CrawlerTrait.php:50
PHP  16. Illuminate\Foundation\Testing\TestCase->call() /usr/share/nginx/html/like_award_php/vendor/laravel/framework/src/Illuminate/Foundation/Testing/CrawlerTrait.php:151

原因

使い方間違えたかなーと思ってコード呼んだりggったりしてたけど結論としてはPHPの挙動のせいでした。

PHPではクラスのインスタンスが生成される時、クラス名と同じメソッドがあるとそれをコンストラクターとして実行します。

先ほどのテストコードを見るとクラス名と同じテストメソッドを作ってしまったため、setUp()によりアプリケーションが生成される前にテストを実行してしまったのでした。

まとめ

PHP力が足りない

ちなみにPHP7ではこの仕様はなくなるようです。メシア。