0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

メモ: laravel で trait を使って static method で Event 登録するような時に Mockery を使って UnitTest を書く方法

Posted at

よく忘れるので自分用のメモ。

何を実現したいか

例えば、以下のような Trait が存在して、 static::deleted() の Closure も Mockery を使って UnitTest でカバーしたい時の方法。

trait SomeTrait
{
    /**
     * boot
     */
    public static function bootSomeTrait()
    {
        static::deleted(function ($model) {
            $model->someModelsMethod();
        });
    }
}

どうやって実現するか

以下のようにすると closure 部分も UnitTest でカバーできるようになる。


final class SomeTraitTest extends TestCase
{
    public function testSomeTrait()
    {
        $class = new class {
            use SomeTrait;
            
            public static function deleted($closure)
            {
                $mock = Mockery::mock(stdClass::class);
                $mock->shouldReceive('someModelsMethod')->once()->with();
                $closure($mock);
            }
        };
        
        $class::bootSomeTrait();
    }
}

anonymous class 内で use SomeTrait して、 SomeTrait が用いる public static function deleted($closure) を anonymous class に定義する。

この anonymous class の引数である $closureSomeTraitstatic::deleted(function ($model) {...} の function 部分が引数なので、 callable となる。

なので、ここで適切に Mockery 等を使って何らかの手続を確認するように書けば良い。

注意点とか

anonymous class(無名クラス)使ってるので、当然 PHP7 以上じゃないとダメ。

laravel で event を登録する処理を書くなら、素直に Observer 使うべきだと思う。 https://laravel.com/docs/5.8/eloquent#observers

ただ、外部のパッケージで便利なやつがあって、それが Trait で実現されてて…かつ、そのパッケージに少しだけオリジナルな処理を追加したい時とかに、 trait ベースで Event 登録が必要になったりする。

あと parent::otherMethod(); とかある場合は、このアプローチは使えない。(anonymous class 使ってるので親が居ないので当然。)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?