CodeIgniter3でのテスト
CodeIgniter3でのテストについて、資料を作りましたので公開します。
(2020-03-29 追記) 見やすいようにマインドマップを更新し、マップの内容を本文に追記しました。
プレゼン資料
CodeIgniterのアーキテクチャ
CodeIgniterインスタンス
get_instance()
で取得できるヤツ- 神オブジェクト的なシングルトンぽいもの
- 実体はControllerのインスタンス
- 想定
- 1つのリクエストで1つしか生成されない
CI_Loaderクラス
- モデル、ライブラリなどをロードするもの
- 生成されたインスタンスをCodeIgniterインスタンスのプロパティに動的に追加する
- CodeIgniterインスタンスが神オブジェクト化する
$this->foo
がコントローラ、モデルで同じように使える
- 関数にも依存している
load_class()
is_loaded()
CodeIgniter3のテスト上の問題点
グローバル状態
- シングルトン
- グローバル変数
- 関数内のスタティック変数
exit() での終了
クラス名の衝突
- 複数のコントローラに全く同じクラス名を付けられる
隠れた依存
ci-phpunit-test
ci-phpunit-testとは?
- CodeIgniter3とPHPUnitをつなぐブリッジツール
- 基本はPHPUnit
- CodeIgniter本体のコードの書き換えは一切不要
アーキテクチャ
- グローバル状態のリセット
- CodeIgniterインスタンスのリセット
- 構成
- オートローダ
- CodeIgniterのファイルの動的な置き換え
- テスト上の問題点を解消する
$this->request
によるControllerの機能テスト- ヘルパークラスやメソッド
- テストコードを書きやすくするためのもの
- ヘルパークラス
ReflectionHelper
- ヘルパーメソッド
$this->getDouble()
- Monkey Patch
- ライブラリとして実装されている
- 自転車の補助輪のようなもの
- 最後の手段
テスト作成上のテクニック
resetInstance()
- 何をするか?
- CodeIgniterインスタンスをリセットする
- 新しいCodeIgniterインスタンスを生成する
$this->CI
にCodeIgniterインスタンスを代入する
- 呼び出し不要
newController()
/newLibrary()
/newModel()
を使う場合$this->request
を使う場合
依存オブジェクトの注入
- CI_Loaderにより作成されたプロパティはすべて動的なプロパティ
- つまりpublic
- インスタンス化後には外から注入可能
- つまりpublic
- Controllerのテストの場合
setCallable()
/addCallable()
でプロパティにモックを注入すればよい
サンプルテストコード
- https://github.com/kenjis/codeigniter-tettei-apps/tree/develop/application/tests
- https://github.com/kenjis/ci-app-for-ci-phpunit-test/tree/master/application/tests
さらに学習するには?
Date: 2017/09/22