環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G1212
'TMP'が定義されていない
Use of undefined constant TMP - assumed 'TMP'
なんぞこれ?
コードを追っていくと、下記コードでエラーが発生していた。
// ... protected static function _defaultConfig($name) { $defaults = [ 'php' => [ 'cookie' => 'CAKEPHP', 'ini' => [ 'session.use_trans_sid' => 0, ] ], 'cake' => [ 'cookie' => 'CAKEPHP', 'ini' => [ 'session.use_trans_sid' => 0, 'session.serialize_handler' => 'php', 'session.use_cookies' => 1, 'session.save_path' => TMP . 'sessions', // <- ここ 'session.save_handler' => 'files' ] ], // ... } // ...
要は、「"TMP"って定数が宣言されていないぞコラァー!」ってことだと思う。
過去こういうのでハマんなかったかな? ってことで思い出した。
そそ! これこれ。
$ ~/vendor/bin/phpunit --configuration ~/phpunit.xml.dist
./config/bootstra.php
が見つからない
Warning Error: require_once(./config/bootstrap.php): failed to open stream: No such file or directory in ...
次はなにー?
<?php //... public function bootstrap() { require_once $this->configDir . '/bootstrap.php'; } // ...
ここで発生している。
予備元を順に追っていきます。
<?php // ... public function run(ServerRequestInterface $request = null, ResponseInterface $response = null) { $this->app->bootstrap(); // ...
<?php // ... public function execute($request) { try { $reflect = new ReflectionClass($this->_class); $app = $reflect->newInstanceArgs($this->_constructorArgs); // (´・ω・`) } catch (ReflectionException $e) { throw new LogicException(sprintf( 'Cannot load "%s" for use in integration testing.', $this->_class )); } // Spy on the controller using the initialize hook instead // of the dispatcher hooks as those will be going away one day. EventManager::instance()->on( 'Controller.initialize', [$this->_test, 'controllerSpy'] ); $server = new Server($app); $psrRequest = $this->_createRequest($request); $response = $server->run($psrRequest); // ここの中でbootstrap()を呼んでエラーが発生する return ResponseTransformer::toCake($response); } // ...
(´・ω・`)のところで、渡している値$this->_constructorArgs
の中が、./config
となっているがダメ。
PhpStormのデバッグの設定では相対パスで設定すると何故かエラーになるので、絶対に変更しなければならない。
どうにかこいつの値を変更できないものか。と、調べていたら
<?php public function __construct($test, $class = null, $constructorArgs = null) { $this->_test = $test; $this->_class = $class ?: Configure::read('App.namespace') . '\Application'; $this->_constructorArgs = $constructorArgs ?: ['./config']; // ここ }
__construct
で、設定されていた。三項演算子なので、$constructorArgs
の値がnull
なのがダメ。
じゃあ、このクラスをオブジェクト化しているのはどこか。
<?php // ... protected function _makeDispatcher() { if ($this->_useHttpServer) { return new MiddlewareDispatcher($this, $this->_appClass, $this->_appArgs); // ここ } return new LegacyRequestDispatcher($this); } // ...
ふむう。じゃあ、この、$this->_appArgs
ってのはどこで設定されているのかなー。
<?php // ... public function configApplication($class, $constructorArgs) { $this->_appClass = $class; $this->_appArgs = $constructorArgs; } // ...
みつけたぁあああ!!
ってことは、このメソッドがあるクラスを継承しているテストクラスでそのまま呼べんじゃん!
ってことで、試す。
- 自分のテストクラス
<?php // ... public function testIndex() { $path = '<絶対パス>'; $this->configApplication(null, [$path]); // 配列で渡す $this->post('/schedule-api/get', $postData); // ... }
うまくいったぁああああああああ!!!!
うまくいったけど
って、ちょいまち。
そもそも、コマンドの引数でbootstrap.phpを指定できないのか? と、疑問に思った瞬間、記憶が戻ってきた。
$ ~/vendor/bin/phpunit --bootstrap ~/tests/bootstrap.php ~/tests/
(°ω°; マサカ...!?
・・・できませんでした。( ´ー`)フゥー...
いや、よくないけどね。
なんででしょー?
うーん。そもそも、設定するのが、configApplication()
のメソッドなら、こいつをコールしている箇所を探せばいいはず。
$ grep 'configApplication' -r ~/vendor/ ~/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestCase.php: public function configApplication($class, $constructorArgs)
Oh...
どこも呼んでないやん。
よくわからんが、とりあえずconfigApplication()
をsetup()
で呼んで設定することにしました。
<?php // ... public function setUp() { $this->configApplication(null, [ROOT . 'config']); parent::setUp(); } // ...