Readouble

Laravel 5.3 モック

イントロダクションIntroduction

Laravelアプリケーションをテストする場合、特定のテストの間は実際に実行されないように、アプリケーションの明確な一部を「モック」したくなります。たとえば、イベントを発行するコントローラをテストする時に、テストの間は実際に実行したくないので、イベントリスナーをモックしたいと思うことでしょう。これにより、コントローラのHTTPレスポンスだけをテストし、イベントリスナーの実行を心配しなくて済みます。なぜなら、イベントリスナーは自身のテストケースにおいて、テストできるからです。When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. For example, when testing a controller that fires an event, you may wish to mock the event listeners so they are not actually executed during the test. This allows you to only test the controller's HTTP response without worrying about the execution of the event listeners, since the event listeners can be tested in their own test case.

Laravelにはイベント、ジョブ、ファサードを最初からモックできるヘルパが準備されています。これらのヘルパは主にMockery上で動作する便利なレイヤーを提供しているので、複雑なMockeryのメソッドコールを自分で作成する必要はありません。もちろん、MockeryやPHPUnitを使用し、自身のモックやスパイを自由に作成してください。Laravel provides helpers for mocking events, jobs, and facades out of the box. These helpers primarily provide a convenience layer over Mockery so you do not have to manually make complicated Mockery method calls. Of course, you are free to use Mockery[http://docs.mockery.io/en/latest/] or PHPUnit to create your own mocks or spies.

イベントEvents

モックの使用Using Mocks

Laravelのイベントシステムを多用している場合、テスト中は静かにしてもらうか、特定のイベントモックしたいと思うでしょう。たとえばユーザ登録のテスト中は、たぶんUserRegisteredイベントのハンドラには全部起動してもらいたくないでしょう。なぜなら、"Welcome"メールが送られて…などが起きるからです。If you are making heavy use of Laravel's event system, you may wish to silence or mock certain events while testing. For example, if you are testing user registration, you probably do not want all of a UserRegistered event's handlers firing, since the listeners may send "welcome" e-mails, etc.

Laravelはイベントハンドラを実行させずに期待するイベントが発行されたことを確認する、便利なexpectsEventsメソッドを用意しています。Laravel provides a convenient expectsEvents method which verifies the expected events are fired, but prevents any listeners for those events from executing:

<?php

use App\Events\UserRegistered;

class ExampleTest extends TestCase
{
    /**
     * 新ユーザの登録テスト
     */
    public function testUserRegistration()
    {
        $this->expectsEvents(UserRegistered::class);

        // ユーザ登録のテスト…
    }
}

指定したイベントが発行されないことを確認するには、doesntExpectEventsメソッドを使います。You may use the doesntExpectEvents method to verify that the given events are not fired:

<?php

use App\Events\OrderShipped;
use App\Events\OrderFailedToShip;

class ExampleTest extends TestCase
{
    /**
     * 注文発送のテスト
     */
    public function testOrderShipping()
    {
        $this->expectsEvents(OrderShipped::class);
        $this->doesntExpectEvents(OrderFailedToShip::class);

        // 注文発送のテスト…
    }
}

全イベントハンドラの実行を停止したい場合は、withoutEventsメソッドを使用してください。このメソッドが呼び出されると、全イベントの全リスナーはモックされます。If you would like to prevent all event listeners from running, you may use the withoutEvents method. When this method is called, all listeners for all events will be mocked:

<?php

class ExampleTest extends TestCase
{
    public function testUserRegistration()
    {
        $this->withoutEvents();

        // ユーザ登録コードのテスト…
    }
}

Fakeの使用Using Fakes

モックの代替として、Eventファサードのfakeメソッドを使い、全イベントリスナーの実行を停止できます。その後に、発行されたイベントをアサートし、受け取ったデータを調べることも可能です。Fakeを使用する場合、テスト対象のコードを実行した後に、アサートを作成してください。As an alternative to mocking, you may use the Event facade's fake method to prevent all event listeners from executing. You may then assert that events were fired and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

<?php

use App\Events\OrderShipped;
use App\Events\OrderFailedToShip;
use Illuminate\Support\Facades\Event;

class ExampleTest extends TestCase
{
    /**
     * 注文のテスト
     */
    public function testOrderShipping()
    {
        Event::fake();

        // 注文の実行コード…

        Event::assertFired(OrderShipped::class, function ($e) use ($order) {
            return $e->order->id === $order->id;
        });

        Event::assertNotFired(OrderFailedToShip::class);
    }
}

ジョブJobs

モックの使用Using Mocks

時には、アプリケーションへリクエストを作成したら、特定のジョブがディスパッチされるかをテストしたいこともあるでしょう。これによりジョブのロジックについて心配せずに、切り離してルートやコントローラをテストできます。もちろん、それから切り離したテストケースで、ジョブをテストすべきです。Sometimes, you may wish to test that given jobs are dispatched when making requests to your application. This will allow you to test your routes and controllers in isolation without worrying about your job's logic. Of course, you should then test the job in a separate test case.

Laravelは便利なexpectsJobsメソッドを用意しており、期待しているジョブがディスパッチされたかを検査できます。しかしジョブ自身は実行されません。Laravel provides the convenient expectsJobs method which will verify that the expected jobs are dispatched. However, the job itself will not be executed:

<?php

use App\Jobs\ShipOrder;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        $this->expectsJobs(ShipOrder::class);

        // 注文の発送をテスト…
    }
}

Note: note このメソッドはDispatchesJobsトレイトのdispatchメソッドか、dispatchヘルパ関数により起動されたジョブだけを検知します。直接Queue::pushで送られたジョブは検知できません。{note} This method only detects jobs that are dispatched via the DispatchesJobs trait's dispatch methods or the dispatch helper function. It does not detect queued jobs that are sent directly to Queue::push.

イベントモックヘルパのように、doesntExpectJobsメソッドを利用し、ジョブをディスパッチせずにテストできます。Like the event mocking helpers, you may also test that a job is not dispatched using the doesntExpectJobs method:

<?php

use App\Jobs\ShipOrder;

class ExampleTest extends TestCase
{
    /**
     * 注文キャンセルのテスト
     */
    public function testOrderCancellation()
    {
        $this->doesntExpectJobs(ShipOrder::class);

        // 注文キャンセルのテスト…
    }
}

もしくは、withoutJobsメソッドを使い、全ディスパッチジョブを無効にできます。あるテストメソッド内でこのメソッドを呼び出すと、そのテストの間にディスパッチされた全ジョブは破棄されます。Alternatively, you may ignore all dispatched jobs using the withoutJobs method. When this method is called within a test method, all jobs that are dispatched during that test will be discarded:

<?php

use App\Jobs\ShipOrder;

class ExampleTest extends TestCase
{
    /**
     * 注文キャンセルのテスト
     */
    public function testOrderCancellation()
    {
        $this->withoutJobs();

        // 注文キャンセルのテスト…
    }
}

Fakeの使用Using Fakes

モックの代替として、Queueファサードのfakeメソッドを使い、ジョブがキューされるのを防ぐことができます。その後で、ジョブがキューへ投入されたことをアサートし、受け取ったデータの内容を調べることもできます。Fakeを使う場合は、テスト対象のコードを実行した後で、アサートしてください。As an alternative to mocking, you may use the Queue facade's fake method to prevent jobs from being queued. You may then assert that jobs were pushed to the queue and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

<?php

use App\Jobs\ShipOrder;
use Illuminate\Support\Facades\Queue;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        Queue::fake();

        // 注文発送のコード実行…

        Queue::assertPushed(ShipOrder::class, function ($job) use ($order) {
            return $job->order->id === $order->id;
        });

        // 特定のキューへジョブが投入されたことをアサート
        Queue::assertPushedOn('queue-name', ShipOrder::class);

        // ジョブが投入されなかったことをアサート
        Queue::assertNotPushed(AnotherJob::class);
    }
}

MailのFakeMail Fakes

Mailファサードのfakeメソッドを使い、メールが送信されるのを防ぐことができます。その後で、Mailableがユーザへ送信されたかをアサートし、受け取ったデータを調べることさえできます。Fakeを使用する場合、テスト対象のコードが実行された後で、アサートしてください。You may use the Mail facade's fake method to prevent mail from being sent. You may then assert that mailables[/docs/{{version}}/mail] were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

<?php

use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        Mail::fake();

        // 注文コードの実行…

        Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
            return $mail->order->id === $order->id;
        });

        // メッセージが指定したユーザに届いたことをアサート
        Mail::assertSentTo([$user], OrderShipped::class);

        // Mailableが送られなかったことをアサート
        Mail::assertNotSent(AnotherMailable::class);
    }
}

NotificationのFakeNotification Fakes

Notificationファサードのfakeメソッドを使用し、通知が送られるのを防ぐことができます。その後で、通知がユーザへ送られたことをアサートし、受け取ったデータを調べることさえできます。Fakeを使用するときは、テスト対象のコードが実行された後で、アサートを作成してください。You may use the Notification facade's fake method to prevent notifications from being sent. You may then assert that notifications[/docs/{{version}}/notifications] were sent to users and even inspect the data they received. When using fakes, assertions are made after the code under test is executed:

<?php

use App\Notifications\OrderShipped;
use Illuminate\Support\Facades\Notification;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        Notification::fake();

        // 注文発送コードの実行…

        Notification::assertSentTo(
            $user,
            OrderShipped::class,
            function ($notification, $channels) use ($order) {
                return $notification->order->id === $order->id;
            }
        );

        // 通知が指定したユーザへ送られたことをアサート
        Notification::assertSentTo(
            [$user], OrderShipped::class
        );

        // 通知が送られなかったことをアサート
        Notification::assertNotSentTo(
            [$user], AnotherNotification::class
        );
    }
}

ファサードFacades

伝統的な静的メソッドの呼び出しと異なり、ファサードはモックできます。これにより伝統的な静的メソッドより遥かなアドバンテージを得られ、依存注入を使用する場合と同じテストビリティを持てます。テスト時、コントローラのLaravelファサード呼び出しを頻繁にモックしたくなります。たとえば、以下のようなコントローラアクションを考えてください。Unlike traditional static method calls, facades[/docs/{{version}}/facades] may be mocked. This provides a great advantage over traditional static methods and grants you the same testability you would have if you were using dependency injection. When testing, you may often want to mock a call to a Laravel facade in one of your controllers. For example, consider the following controller action:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * アプリケーションの全ユーザーリストの表示
     *
     * @return Response
     */
    public function index()
    {
        $value = Cache::get('key');

        //
    }
}

shouldReceiveメソッドを使用し、Cacheファサードへの呼び出しをモックできます。これはMockeryインスタンスを返します。ファサードはLaravelのサービスコンテナにより管理され、依存解決されていますので、典型的な静的クラスよりもかなり高いテスタビリティーを持っています。例としてCacheファサードへのgetメソッド呼び出しをモックしてみましょう。We can mock the call to the Cache facade by using the shouldReceive method, which will return an instance of a Mockery[https://github.com/padraic/mockery] mock. Since facades are actually resolved and managed by the Laravel service container[/docs/{{version}}/container], they have much more testability than a typical static class. For example, let's mock our call to the Cache facade's get method:

<?php

class FooTest extends TestCase
{
    public function testGetIndex()
    {
        Cache::shouldReceive('get')
                    ->once()
                    ->with('key')
                    ->andReturn('value');

        $this->visit('/users')->see('value');
    }
}

Note: note Requestファサードはモックしてはいけません。テスト実行時は代わりに、callpostのようなHTTPヘルパメソッドへ望みの入力を渡してください。同様に、テストではConfigファサードをモックする代わりに、Config::setメソッドを呼び出してください。{note} You should not mock the Request facade. Instead, pass the input you desire into the HTTP helper methods such as call and post when running your test. Likewise, instead of mocking the Config facade, simply call the Config::set method in your tests.

章選択

開発環境
ビューとテンプレート
公式パッケージ

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作