Help us understand the problem. What is going on with this article?

EloquentModelを使ってエンティティを取得しているメソッドのユニットテストの書き方

背景

例えばTestModel::findOrFail()とか中でしているメソッドのユニットテストを書くと、どうしてもDBが絡んでユニットテストではなくなってしまう。
これの解決方法。

結論

ExampleService
use App\ExampleModel;

class ExampleService {
    private $exampleModel;

    public function __construct(ExampleModel $exampleModel)
    {
        $this->exampleModel = $exampleModel;
    }

    public function func()
    {
        ...
        $this->exampleModel->findOrfail($id);
        ...
    }
}
ExampleServiceTest
use App\ExampleModel;

...

    $exampleModel = Mockery::mock('\App\ExampleModel')
    $entity = new stdClass;
    $entity->name = $name;
    $exampleModel
        ->shouldReceive('findOrFail')
        ->with($id)
        ->andReturn($entity);
    app()->instance(ExampleModel::class, $exampleModel);
...

解説

EloquentModelはコンストラクタインジェクションで入れておいて、builder機能をインスタンスメソッドで使う

例えばfindOrFail()メソッドなんかはよくstaticメソッドとして実行されるが、内部的には(new static)->$method()とかやってるだけなので、インスタンスメソッドとして実行しても同じものが得られる。
それであればテストの観点からコンストラクタインジェクションで外部からオブジェクトをもらった方が良い。

テストにおいてEloquentModelのクラス名でサービスコンテナに入れておく

Laravelのコンストラクタインジェクションは、そのクラス名でサービスコンテナに探し行く。つまり内部的にはapp()->make(ExampleModel::class)で取ってきていると考えられる。
そうであれば、そのクラス名でmockをサービスコンテナに登録しておけば、テスト時にDBが絡むことを防ぐことが出来る。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away