静的メソッドを使用してサービスクラスを使用しないでください


このポストの文脈のサービスクラスは、ドメインロジックをカプセル化するのに用いられるクラスです.たとえば、新しいブログ記事を作成するためにエンドポイントを作成するとき、多くの場合、コントローラに直接操作するのではなく、サービスクラスメソッドの内部にその新しいポストを作成するコアロジックを置くことになります.
開発者がそのロジックをカプセル化するのを選択する理由は、通常、プロジェクト内の他の場所で再利用することができます.たとえば、ブログ投稿を作成するときはフロントエンドの実装やAPIを通して可能です.

静的メソッドがなぜ最初に使われるのか


このパターンがなぜ使用されるのかを正確に判断するのは難しいですが、私の推測はこれです.クラスを使用可能なファサードに変えるために、ボイラー板を書き出す代わりに、それはAstatic メソッドの前のキーワード.そして、ファサードのように、それはきれいに見えます.任意の醜い依存性の注射を行う必要はありません.
class PostService
{
  public static function create()
  {
    // do some creating...
  }
}

class PostController
{
  public function store(Request $request)
  {
    // validate and whatever else...
    PostService::create($request->all());

    return back();
  }
}
それは素晴らしい見ていませんか?

なぜそれをしないでください


テスト
あなたはこれらのサービスクラスを利用する何かをテストしようとするのに時間がかかるでしょう.サービスを使用するコントローラメソッドをテストしているとしましょう.そのサービスは舞台裏で複雑なロジックをたくさんする.あなたは、サービスがテストの中から失敗なしで実行する必要があるすべてを手配しなければならないでしょう.この他の無関係なものをテストするすべて.
そこには方法があるmock a static method , しかし、mockeryドキュメンテーションの中で直接述べられても、推奨されません.
物語のモラルは、自分自身の道を下に頭痛の多くを保存し、古風な依存性の注入で固執する.Laravelを使用すると、コンテナを使用して依存関係のすべてを自動解決することができます.

最も簡単な選択肢


class PostController
{
  public function store(Request $request, PostService $service)
  {
    // validate and whatever else...
    $service->create($request->all());

    return back();
  }
}
正直にしましょう、上記のコード・ブロックはそれほど悪くはありません、特にあなたがどれくらいの簡単なテストであるかについて考えるとき.

ハウツーテスト


LaraVelはコンテナを利用して依存関係を自動解決しますa way to hijack that and sub in a mocked version .
$this->mock(PostService::class, function (MockInterface $mock) {
    $mock->shouldReceive('create')->once();
});