開発室ブログ

JSON

テストデータへの悩み(前編)

あけましておめでとうございます。年末年始は実家に帰ってゆっくりしていた開発室員Tです。新年最初の仕事はブログ書きになりました。これ書いてる間に2019年に置いてきた仕事を思い出せればよいのですが。

まあ相も変わらずテストについてですが。今回は内容薄めかもしれません。去年はテストで始まりテストで終わった感があったので、今年もテストで始めます。

まえがき

今回のテスト記事、このこと だけ しか話さないと思います。書いてる途中にほかの話が入りそうですが、ほんと昨年は最初から最後までこいつに苦しみました。

特にJSON、テメェは許さねぇ

今まさに作成しているAPI、他のサイトさんのAPIを使用しているのですが、当然の如くテスト流すたびにAPIを流していたら時間はかかるわ結果は変わるわ。なのでLaravelのテストで標準搭載されている Mockery を使っているのです。

こいつこいつ。

$mock = \Mockery::mock(モックにしたいクラス);
$mock->shouldReceive(モックにしたい関数名)->andReturn(返したいデータ達);
$this->app->instance(サービスプロバイダでbindしている名前, $mock);

そうこの 返したいデータ達 。こいつらがJSONなんですよ。しかもそのデータのひとつはとてつもなく長~~~~~~~~~~~~~~~~~~~~いやつ。ブログに書くと文字数やばいことになるのでできませんが、その文字数は 約40,000文字 と。多すぎですね。JSONなら仕方ないのかもしれませんが、多すぎですね、ええ。

しかもこのデータ、各単体テストの至るところで出てくるので、その都度この長~~~~~~~~~~~~~~~~~~~~いやつをテストに書いてたら酷いことになるんですよ。なので、テストデータだけ分離して再利用できるようにします。

Trait化

再利用といえばこいつですよね。

はい、というわけでトレイトはこう。

<?php

trait TestData {
    public function getTestData_TestA () {
        return 長~~~~~~~~~~~~~~~~~~~~いやつ。;
    }
}

テスト本体はこれで。

<?php

namespace Tests\Unit;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use Tests\TestData;

class AuditTest extends TestCase
{
    use TestData;

    public function test_MethodA () {
        $mock = \Mockery::mock(モックにしたいクラス);
        $mock->shouldReceive(モックにしたい関数名)->andReturn($this->getTestData_TestA());
        $this->app->instance(サービスプロバイダでbindしている名前, $mock);
    }
}

こんな感じで作っていけばいいんですが、こういうの書いてるといろいろ思うことはあるわけで。

IOとかActualとかExpectedとかどうするよ

と。まさに今ここにいます。そうだよこの形をどうするかで悩んで仕事納めしたんだよちくしょう面倒なの残しちまってた。

・・・という茶番はさておき。年をまたぐ前に「これならいけるんじゃね?」という形を残していました。

またもうひとつ前置きですが 記載している方法が必ずしもすべてのテストケースにHITするわけではありません のでご了承ください。

まず基本的なテストの流れはどこもこんな感じだと思います。

  1. モックを作る
  2. テストしたい関数を呼び出す
  3. 呼び出した値と期待する値が合っているか確認する

また、テストしたい関数によっては引数が必要なときもありますね。なので、ざっくりとテストデータはこれらに絞られます。

  1. モックとして呼び出した関数が返すデータ
  2. テストしたい関数からの出力として期待するデータ
  3. テストしたい関数に入れるデータ(任意)

というわけで、テストデータをまとめたクラスはこのような形になりました。

<?php

trait TestData {
    public function getTestData_TestA() {
        return [
            'mock' => なにか,
            'expected' => なにか,
            'input' => なにか,
        ];
    }
}

さて、ここまで書いていて不穏に思った方もいるのではないでしょうか。

結局テストごとにメソッド用意してたら、何個も長~~~~~~~~~~~~~~~~~~~~いやつを書くのでは・・・?

そうなんだよなーーーーーー

ええそうです。

まさにそうです。

ほんとそうなんです。

思い出しました。mock,expected,inputの3つの形にした配列を返すというものに辿り着いたまさにそのとき。 この問題にぶち当たって大掃除の時間になったんです。

はい、なので今日の作業はこれの結論を出すところからスタートとなります。

さいごに

というわけでテストデータへの悩み(前編)と題して書いていきました。いやぁ、仕事内容思い出せてよかったよかった。

そうはいうものの、やはりテストって奥が深いですね。そこが面白いところでもあるのですが。

今回問題となったJSONデータのモック化については次の記事でも同じこと書くかもしれませんが、使用しているAPIの出力形式が変われば当然それに対応する必要が出てくるので、テストデータも変更しやすいように作らないといけないんですよね。

これをいまのうちにやっておかないと、いざAPIの出力が変更されたときに時間かかっちゃったり、テストとして意味をなさなくなるので。

たかがテストデータ。されどテストデータ。深くて楽しいです。いい沼ですよ。

RecentPost