もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

Mockeryのwith()を使う際に引数にオブジェクトをそのまま渡せない

はじめに

こんばんは。

phpunitのモックライブラリの prophecy をずっと使っていたのですが、最近 laravelの案件をやりはじめてMockery使ってテスト書くにあたりちょっと勝手が違った部分があったので、備忘録で残しておきます。

内容はタイトルのとおりです。

php version, laravel versionは以下

 # php -v
PHP 7.4.26

# php artisan -V
Laravel Framework 8.83.0

本題

今回の場合は引数にlaravelの collection を渡すようなメソッドのモックを作りたい感じでした。

prophecy の場合は以下みたいな感じでだと思います。

$mockA = $this->prophesize(aaa::class);
$mockA->toArray()->willReturn([xxxx]);

$mockB = $this->prophesize(bbb::class);
$mockB->register($pk, $mockA->reveal())->shouldBeCalledOnce();

Mockery の場合は以下みたいな感じでした。

$collection = collect([xxxx]);
$mockA = \Mockery::mock(aaa::class)->makePartial();
$mockA->shouldReceive('register')
        ->with(\Mockery::on(function ($actual) use ($collection) {
            $this->assertEquals($actual, $collection);
            return true;
        }))->once();

症状的には こちら の記事と同じだと思います。

prophecy をずっとやってるからなのかもしれませんが、 ちょっと使いづらいと感じてしまいました...

また、こちら の記事では \Hamcrest\Matchers を使う方法も紹介されています。

$collection = collect([xxxx]);
$mockA = \Mockery::mock(aaa::class)->makePartial();
$mockA->shouldReceive('register')
        ->with((\Hamcrest\Matchers::equalTo($collection)))->once();

後者のほうがスッキリしていいですね!

終わりに

ちょっと前に短期案件で久々にテストコードがないプロジェクトにアサインしたのですが、テストコード書きなれると、テストコードがないプロダクトコード触るのが怖すぎて、開発スピードが明らかに落ちてました。

t_wadaさんのスライドにあった

テストを書く時間がないのではなく、テストを書かないから時間がなくなるのです。

っていうのがすごく身にしみました。

speakerdeck.com

現場からは以上です。