東京はサクラ咲きまくってるけど、自分の住んでいるとこ(ちば)は全然咲いていなくて春なのか春じゃないのかよく分からない今日このごろ。
話は変わって、最近やっと案件でもPHPUnit書くようになってきたんだけども(個人的には書いてたよ。ほ、本当だよ。)、どうやってテスト書けばいいねんってケースに出くわしました。
それは、ajaxから呼ばれるプログラムのテストです。
そうっすAPIっす。
返却値(大体json形式ですよね)をechoするやつっす。
echoするやつのテストどうしたらええねんってやつっす。
※こんなやつです
function echoJson() { header("Content-Type: application/json; charset=utf-8"); echo json_encode(array("name"=>"Bob")); }
呼んでも値受け取れないし、むしろ怒られるし。
Cannot modify header information - headers already sent by (output started at phar:///usr/local/bin/phpunit/phpunit/Util/Printer.php:172)
ob_start()
とob_clean()
で囲えば怒られないけど、何か
risky tests!
って言われるし。
2016/12/14 追記
PHPUnitでheader関数を使うメソッドのテスト | Shimabox Blog に書きましたが、@runInSeparateProcess
ob_start()
ob_get_contents()
ob_end_clean()
を使う方法もあります。こちらで実装すれば
risky tests!
って怒られません。
2016/12/14 追記ここまで
でも、モックを使った解決策をちょっと思いついたので記しておきます。
先にソースを
解説
多分ソースを見れば何となく分かると思うんですけど、ミソが、単純に引数で受け取った値をecho(headerも併せて)するメソッドを作っている部分です。
上記でいうとechoJson()
が該当します。
んで、モックの定義をして、expects()
とwith()
を使ってテストします。
expects($this->any())->method('echoJson')のwith($this->equalTo('hoge'))
で、echoJson()は’hoge’が渡される事を期待するって感じになります。
echoJson()に’hoge’と違う値が渡されたらテストがこけます。
上記クラスでいうならば
$expected = json_encode(array("message" => "piyo"));
とすると、
Parameter 0 for invocation Sample::echoJson('{"message":"hoge"}') does not match expected value. Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'{"message":"piyo"}' +'{"message":"hoge"}'
こうなります。
つまり、echoする関数に対してちゃんと期待通りの引数が渡っているよね。ちゃんとした値が渡っていればおkだよねって感じのテストです。
というわけで、ここまでテスト書ければいいんじゃないのかなというのが、ついさっき思いついた自分の解です。何かミスっていたらすいません。
受け取った値をechoするメソッドを持つクラスを作るやり方もあると思います(こっちだとモックらなくてもいい)が、モックりたかったので今回はこれで。
まとめ
処理を分けて、モックを使えばなんとかなる!
最近やっとモックを使ったテストを覚えてきましたが、モックまじヤバイです。パネェっす。近いうちまた何か書きます。