Readouble

Laravel 9.x モック

イントロダクション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 dispatches 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メソッド呼び出しを手作業で行う必要はありません。Laravel provides helpful methods for mocking events, jobs, and other 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.

オブジェクトのモックMocking Objects

Laravelのサービスコンテナを介してアプリケーションに注入されるオブジェクトをモックする場合、モックしたインスタンスをinstance結合としてコンテナに結合する必要があります。これにより、オブジェクト自体を構築する代わりに、オブジェクトのモックインスタンスを使用するようコンテナへ指示できます。When mocking an object that is going to be injected into your application via Laravel's service container[/docs/{{version}}/container], you will need to bind your mocked instance into the container as an instance binding. This will instruct the container to use your mocked instance of the object instead of constructing the object itself:

use App\Service;
use Mockery;
use Mockery\MockInterface;

public function test_something_can_be_mocked()
{
    $this->instance(
        Service::class,
        Mockery::mock(Service::class, function (MockInterface $mock) {
            $mock->shouldReceive('process')->once();
        })
    );
}

これをより便利にするために、Laravelの基本テストケースクラスが提供するmockメソッドを使用できます。たとえば、以下の例は上記の例と同じです。In order to make this more convenient, you may use the mock method that is provided by Laravel's base test case class. For example, the following example is equivalent to the example above:

use App\Service;
use Mockery\MockInterface;

$mock = $this->mock(Service::class, function (MockInterface $mock) {
    $mock->shouldReceive('process')->once();
});

オブジェクトのいくつかのメソッドをモックするだけでよい場合は、partialMockメソッドを使用できます。モックされていないメソッドは、通常どおり呼び出されたときに実行されます。You may use the partialMock method when you only need to mock a few methods of an object. The methods that are not mocked will be executed normally when called:

use App\Service;
use Mockery\MockInterface;

$mock = $this->partialMock(Service::class, function (MockInterface $mock) {
    $mock->shouldReceive('process')->once();
});

同様に、オブジェクトをスパイしたい場合のため、Laravelの基本テストケースクラスは、Mockery::spyメソッドの便利なラッパーとしてspyメソッドを提供しています。スパイはモックに似ています。ただし、スパイはスパイとテスト対象のコードとの間のやり取りを一度記録するため、コードの実行後にアサーションを作成できます。Similarly, if you want to spy[http://docs.mockery.io/en/latest/reference/spies.html] on an object, Laravel's base test case class offers a spy method as a convenient wrapper around the Mockery::spy method. Spies are similar to mocks; however, spies record any interaction between the spy and the code being tested, allowing you to make assertions after the code is executed:

use App\Service;

$spy = $this->spy(Service::class);

// …

$spy->shouldHaveReceived('process');

ファサードのモックMocking Facades

従来の静的メソッド呼び出しとは異なり、ファサードリアルタイムファサードを含む)もモックできます。これにより、従来の静的メソッドに比べて大きな利点が得られ、従来の依存注入を使用した場合と同じくテストが簡単になります。テスト時、コントローラの1つで発生するLaravelファサードへの呼び出しをモックしたい場合がよくあるでしょう。例として、次のコントローラアクションについて考えてみます。Unlike traditional static method calls, facades[/docs/{{version}}/facades] (including real-time facades[/docs/{{version}}/facades#real-time-facades]) may be mocked. This provides a great advantage over traditional static methods and grants you the same testability that you would have if you were using traditional dependency injection. When testing, you may often want to mock a call to a Laravel facade that occurs 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 \Illuminate\Http\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

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;

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

        $response = $this->get('/users');

        // …
    }
}

warning Warning! Requestファサードをモックしないでください。代わりに、テストの実行時に、getpostなどのHTTPテストメソッドに必要な入力を渡します。同様に、Configファサードをモックする代わりに、テストではConfig::setメソッドを呼び出してください。Warning
You should not mock the Request facade. Instead, pass the input you desire into the HTTP testing methods[/docs/{{version}}/http-tests] such as get and post when running your test. Likewise, instead of mocking the Config facade, call the Config::set method in your tests.

ファサードのスパイFacade Spies

ファサードでスパイしたい場合は、対応するファサードでspyメソッドを呼び出します。スパイはモックに似ています。ただし、スパイはスパイとテスト対象のコードとの間のやり取りを一時的に記録しているため、コードの実行後にアサーションを作成できます。If you would like to spy[http://docs.mockery.io/en/latest/reference/spies.html] on a facade, you may call the spy method on the corresponding facade. Spies are similar to mocks; however, spies record any interaction between the spy and the code being tested, allowing you to make assertions after the code is executed:

use Illuminate\Support\Facades\Cache;

public function test_values_are_be_stored_in_cache()
{
    Cache::spy();

    $response = $this->get('/');

    $response->assertStatus(200);

    Cache::shouldHaveReceived('put')->once()->with('name', 'Taylor', 10);
}

Bus FakeBus Fake

ジョブをディスパッチするコードをテストするときは、通常、特定のジョブがディスパッチされたことをアサートするが、実際にはジョブをキューに投入したり、実行したりは行う必要がありません。これは通常、ジョブの実行は、別のテストクラスでテストできるためです。When testing code that dispatches jobs, you typically want to assert that a given job was dispatched but not actually queue or execute the job. This is because the job's execution can normally be tested in a separate test class.

Busファサードのfakeメソッドを使用して、ジョブがキューにディスパッチされないようにすることができます。それから、テスト対象のコードを実行した後、assertDispatchedメソッドとassertNotDispatchedメソッドを使用してアプリケーションがディスパッチしようとしたジョブを調べられます。You may use the Bus facade's fake method to prevent jobs from being dispatched to the queue. Then, after executing the code under test, you may inspect which jobs the application attempted to dispatch using the assertDispatched and assertNotDispatched methods:

<?php

namespace Tests\Feature;

use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Bus;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_orders_can_be_shipped()
    {
        Bus::fake();

        // 注文の実行コード…

        // ジョブがディスパッチされたことをアサート
        Bus::assertDispatched(ShipOrder::class);

        // ジョブがディスパッチされなかったことをアサート
        Bus::assertNotDispatched(AnotherJob::class);

        // 同期的にジョブがディスパッチされたことをアサート
        Bus::assertDispatchedSync(AnotherJob::class);

        // 同期的にジョブがディスパッチされなかったことをアサート
        Bus::assertNotDispatchedSync(AnotherJob::class);

        // レスポンス送信後にジョブがディスパッチされたことをアサート
        Bus::assertDispatchedAfterResponse(AnotherJob::class);

        // レスポンス送信後にジョブがディスパッチされなかったことをアサート
        Bus::assertNotDispatchedAfterResponse(AnotherJob::class);

        // 1つもジョブがディスパッチされないことをアサート
        Bus::assertNothingDispatched();
    }
}

特定の「論理テスト」に合格するジョブがディスパッチされたことをアサートするために、上記利用可能なメソッドへクロージャを渡せます。指定する論理テストに合格するジョブが最低1つディスパッチされた場合、アサーションは成功します。たとえば、ジョブが特定の注文でディスパッチされたことをアサートしたい場合があります。You may pass a closure to the available methods in order to assert that a job was dispatched that passes a given "truth test". If at least one job was dispatched that passes the given truth test then the assertion will be successful. For example, you may wish to assert that a job was dispatched for a specific order:

Bus::assertDispatched(function (ShipOrder $job) use ($order) {
    return $job->order->id === $order->id;
});

ジョブのサブセットのFakeFaking A Subset Of Jobs

もし、特定のジョブだけをディスパッチさせないようにしたい場合は、fakeメソッドへFakeするそのジョブを渡してください。If you only want to prevent certain jobs from being dispatched, you may pass the jobs that should be faked to the fake method:

/**
 * 注文処理のテスト
 */
public function test_orders_can_be_shipped()
{
    Bus::fake([
        ShipOrder::class,
    ]);

    // ...
}

exceptメソッドを使うと、指定したジョブ以外を全てFakeにできます。You may fake all jobs except for a set of specified jobs using the except method:

Bus::fake()->except([
    ShipOrder::class,
]);

ジョブチェーンJob Chains

BusファサードのassertChainedメソッドを使用して、ジョブのチェーンがディスパッチされたことをアサートできます。assertChainedメソッドは、最初の引数にチェーンするジョブの配列を取ります。The Bus facade's assertChained method may be used to assert that a chain of jobs[/docs/{{version}}/queues#job-chaining] was dispatched. The assertChained method accepts an array of chained jobs as its first argument:

use App\Jobs\RecordShipment;
use App\Jobs\ShipOrder;
use App\Jobs\UpdateInventory;
use Illuminate\Support\Facades\Bus;

Bus::assertChained([
    ShipOrder::class,
    RecordShipment::class,
    UpdateInventory::class
]);

上記の例でわかるように、チェーンジョブの配列はジョブのクラス名の配列です。ただし、実際のジョブインスタンスの配列を提供することもできます。そうすることで、Laravelは、ジョブインスタンスが同じクラスであり、アプリケーションがディスパッチしたチェーンジョブと同じプロパティ値を持つことを保証します。As you can see in the example above, the array of chained jobs may be an array of the job's class names. However, you may also provide an array of actual job instances. When doing so, Laravel will ensure that the job instances are of the same class and have the same property values of the chained jobs dispatched by your application:

Bus::assertChained([
    new ShipOrder,
    new RecordShipment,
    new UpdateInventory,
]);

ジョブバッチJob Batches

BusファサードのassertBatchedメソッドを使用して、ジョブのバッチがディスパッチされたことをアサートできます。assertBatchedメソッドへ渡すクロージャは、Illuminate\Bus\PendingBatchのインスタンスを受け取ります。これはバッチ内のジョブを検査するために使用できます。The Bus facade's assertBatched method may be used to assert that a batch of jobs[/docs/{{version}}/queues#job-batching] was dispatched. The closure given to the assertBatched method receives an instance of Illuminate\Bus\PendingBatch, which may be used to inspect the jobs within the batch:

use Illuminate\Bus\PendingBatch;
use Illuminate\Support\Facades\Bus;

Bus::assertBatched(function (PendingBatch $batch) {
    return $batch->name == 'import-csv' &&
           $batch->jobs->count() === 10;
});

ジョブ/バッチ間テストTesting Job / Batch Interaction

さらに、個々のジョブとその裏で動作しているバッチ間の相互作用をテストする必要がある場合があります。例えば、あるジョブがそのバッチの処理をキャンセルしたかどうかをテストする必要があるかもしれません。これを行うには、withFakeBatchメソッドでFakeバッチをジョブへ割り当てる必要があります。withFakeBatchメソッドは、ジョブのインスタンスとFakeバッチを含むタプルを返します。In addition, you may occasionally need to test an individual job's interaction with its underlying batch. For example, you may need to test if a job cancelled further processing for its batch. To accomplish this, you need to assign a fake batch to the job via the withFakeBatch method. The withFakeBatch method returns a tuple containing the job instance and the fake batch:

[$job, $batch] = (new ShipOrder)->withFakeBatch();

$job->handle();

$this->assertTrue($batch->cancelled());
$this->assertEmpty($batch->added);

Event FakeEvent Fake

イベントをディスパッチするコードをテストするときは、イベントのリスナを実際に実行しないようにLaravelに指示することを推奨します。Eventファサードのfakeメソッドを使用すると、リスナの実行を阻止し、テスト対象のコードを実行してから、assertDispatchedassertNotDispatchedassertNothingDispatchedメソッドを使用してアプリケーションがディスパッチするイベントをアサートできます。When testing code that dispatches events, you may wish to instruct Laravel to not actually execute the event's listeners. Using the Event facade's fake method, you may prevent listeners from executing, execute the code under test, and then assert which events were dispatched by your application using the assertDispatched, assertNotDispatched, and assertNothingDispatched methods:

<?php

namespace Tests\Feature;

use App\Events\OrderFailedToShip;
use App\Events\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;

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

        // 注文の実行コード…

        // イベントがディスパッチされたことをアサート
        Event::assertDispatched(OrderShipped::class);

        // イベントが2回ディスパッチされることをアサート
        Event::assertDispatched(OrderShipped::class, 2);

        // イベントがディスパッチされないことをアサート
        Event::assertNotDispatched(OrderFailedToShip::class);

        // イベントがディスパッチされなかったことをアサート
        Event::assertNothingDispatched();
    }
}

特定の「論理」に合格するイベントがディスパッチされたことをアサートするために、assertDispatchedまたはassertNotDispatchedメソッドへクロージャを渡すことができます。指定する論理テストに合格するイベントが少なくとも1つディスパッチされた場合、アサーションは成功します。You may pass a closure to the assertDispatched or assertNotDispatched methods in order to assert that an event was dispatched that passes a given "truth test". If at least one event was dispatched that passes the given truth test then the assertion will be successful:

Event::assertDispatched(function (OrderShipped $event) use ($order) {
    return $event->order->id === $order->id;
});

イベントリスナが特定のイベントをリッスンしていることを単にアサートしたい場合は、assertListeningメソッドを使用することができます。If you would simply like to assert that an event listener is listening to a given event, you may use the assertListening method:

Event::assertListening(
    OrderShipped::class,
    SendShipmentNotification::class
);

warning Warning! Event::fake()を呼び出した後、イベントリスナはすべて実行されません。したがって、モデルのcreatingイベント中にUUIDを作成するなど、イベントに依存するモデルファクトリをテストで使用する場合は、ファクトリを使用した後にEvent::fake()を呼び出す必要があります。Warning
After calling Event::fake(), no event listeners will be executed. So, if your tests use model factories that rely on events, such as creating a UUID during a model's creating event, you should call Event::fake() after using your factories.

イベントのサブセットのFakeFaking A Subset Of Events

特定のイベントに対してだけ、イベントリスナをFakeしたい場合は、fakefakeForメソッドに指定してください。If you only want to fake event listeners for a specific set of events, you may pass them to the fake or fakeFor method:

/**
 * 受注処理のテスト
 */
public function test_orders_can_be_processed()
{
    Event::fake([
        OrderCreated::class,
    ]);

    $order = Order::factory()->create();

    Event::assertDispatched(OrderCreated::class);

    // その他のイベントは通常通りディスパッチされる
    $order->update([...]);
}

exceptメソッドを使用すると、指定するイベントセットを除外した、残りのイベントをFakeできます。You may fake all events except for a set of specified events using the except method:

Event::fake()->except([
    OrderCreated::class,
]);

限定的なEvent FakeScoped Event Fakes

テストの一部分だけでイベントをFakeしたい場合は、fakeForメソッドを使用します。If you only want to fake event listeners for a portion of your test, you may use the fakeFor method:

<?php

namespace Tests\Feature;

use App\Events\OrderCreated;
use App\Models\Order;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * 注文発送のテスト
     */
    public function test_orders_can_be_processed()
    {
        $order = Event::fakeFor(function () {
            $order = Order::factory()->create();

            Event::assertDispatched(OrderCreated::class);

            return $order;
        });

        // イベントは通常どおりディスパッチされ、オブザーバが実行される
        $order->update([...]);
    }
}

HTTP FakeHTTP Fake

HttpファサードのfakeメソッドでHTTPリクエスト作成時に、スタブした/ダミーのレスポンスを返すようにHTTPクライアントへ指示できます。送信するHTTPリクエストのFakeの詳細は、HTTPクライアントテストのドキュメントを調べてください。The Http facade's fake method allows you to instruct the HTTP client to return stubbed / dummy responses when requests are made. For more information on faking outgoing HTTP requests, please consult the HTTP Client testing documentation[/docs/{{version}}/http-client#testing].

Mail FakeMail Fake

Mailファサードのfakeメソッドを使用して、メールが送信されないようにすることができます。通常、メールの送信は、実際にテストするコードとは関係ありません。ほとんどの場合、Laravelが特定のメールを送信するよう指示されたとアサートするだけで十分です。You may use the Mail facade's fake method to prevent mail from being sent. Typically, sending mail is unrelated to the code you are actually testing. Most likely, it is sufficient to simply assert that Laravel was instructed to send a given mailable.

Mailファサードのfakeメソッドを呼び出した後、mailablesがユーザーに送信されるように指示されたことをアサートし、Mailablesが受信したデータを検査することもできます。After calling the Mail facade's fake method, you may then assert that mailables[/docs/{{version}}/mail] were instructed to be sent to users and even inspect the data the mailables received:

<?php

namespace Tests\Feature;

use App\Mail\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;

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

        // 注文の実行コード…

        // mailableが送信されなかったことをアサート
        Mail::assertNothingSent();

        // mailableが送られたことをアサート
        Mail::assertSent(OrderShipped::class);

        // mailableが2回送信されたことをアサート
        Mail::assertSent(OrderShipped::class, 2);

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

バックグラウンドで配信するためにMailableをキュー投入する場合は、assertSentの代わりにassertQueuedメソッドを使用する必要があります。If you are queueing mailables for delivery in the background, you should use the assertQueued method instead of assertSent:

Mail::assertQueued(OrderShipped::class);

Mail::assertNotQueued(OrderShipped::class);

Mail::assertNothingQueued();

特定の「論理テスト」に合格したMailableが送信されたことをアサートするために、assertSentassertNotSentassertQueuedassertNotQueuedメソッドにクロージャを渡すこともできます。指定する論理テストに合格するMailableが少なくとも1つ送信された場合、アサーションは成功します。You may pass a closure to the assertSent, assertNotSent, assertQueued, or assertNotQueued methods in order to assert that a mailable was sent that passes a given "truth test". If at least one mailable was sent that passes the given truth test then the assertion will be successful:

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

Mailファサードのアサートメソッドを呼び出すと、引数中のクロージャが受け取るMailableインスタンスは、Mailableを調べる便利なメソッドを提供しています。When calling the Mail facade's assertion methods, the mailable instance accepted by the provided closure exposes helpful methods for examining the mailable:

Mail::assertSent(OrderShipped::class, function ($mail) use ($user) {
    return $mail->hasTo($user->email) &&
           $mail->hasCc('...') &&
           $mail->hasBcc('...') &&
           $mail->hasReplyTo('...') &&
           $mail->hasFrom('...') &&
           $mail->hasSubject('...');
});

Mailableインスタンスは、添付ファイルを調べるために便利なメソッドもいくつか持っています。The mailable instance also includes several helpful methods for examining the attachments on a mailable:

use Illuminate\Mail\Mailables\Attachment;

Mail::assertSent(OrderShipped::class, function ($mail) {
    return $mail->hasAttachment(
        Attachment::fromPath('/path/to/file')
                ->as('name.pdf')
                ->withMime('application/pdf')
    );
});

Mail::assertSent(OrderShipped::class, function ($mail) {
    return $mail->hasAttachment(
        Attachment::fromStorageDisk('s3', '/path/to/file')
    );
});

Mail::assertSent(OrderShipped::class, function ($mail) use ($pdfData) {
    return $mail->hasAttachment(
        Attachment::fromData(fn () => $pdfData, 'name.pdf')
    );
});

メールが送信されなかったことを宣言する方法として、assertNotSentassertNotQueuedの2つの方法があるのにお気づきでしょうか。時には、メールが送信されなかったこと、またはキューに入れられなかったことをアサートしたい場合があります。これを実現するには、assertNothingOutgoingassertNotOutgoingメソッドを使用してください。You may have noticed that there are two methods for asserting that mail was not sent: assertNotSent and assertNotQueued. Sometimes you may wish to assert that no mail was sent or queued. To accomplish this, you may use the assertNothingOutgoing and assertNotOutgoing methods:

Mail::assertNothingOutgoing();

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

Mailable内容のテストTesting Mailable Content

Mailableの内容のテストと、Mailableが特定のユーザーへ「送信」されたことをアサートするテストは別にすることをお勧めします。Mailableの内容をテストする方法は、Mailablesのテストのドキュメントを参照してください。We suggest testing the content of your mailables separately from your tests that assert that a given mailable was "sent" to a specific user. To learn how to test the content of your mailables, check out our documentation on the testing mailables[/docs/{{version}}/mail#testing-mailables].

Notification FakeNotification Fake

Notificationファサードのfakeメソッドを使用して、通知が送信されないようにすることができます。通常、通知の送信は、実際にテストしているコードとは関係ありません。ほとんどの場合、Laravelが特定の通知を送信するように指示したことをアサートするだけで十分です。You may use the Notification facade's fake method to prevent notifications from being sent. Typically, sending notifications is unrelated to the code you are actually testing. Most likely, it is sufficient to simply assert that Laravel was instructed to send a given notification.

Notificationファサードのfakeメソッドを呼び出した後、通知がユーザーへ送信されるように指示されたことをアサートし、通知が受信したデータを検査することもできます。After calling the Notification facade's fake method, you may then assert that notifications[/docs/{{version}}/notifications] were instructed to be sent to users and even inspect the data the notifications received:

<?php

namespace Tests\Feature;

use App\Notifications\OrderShipped;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

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

        // 注文の実行コード…

        // 通知がまったく送られていないことをアサート
        Notification::assertNothingSent();

        // 指定するユーザーに通知が送信されたことをアサート
        Notification::assertSentTo(
            [$user], OrderShipped::class
        );

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

        // 指定した数の通知が送信されたことをアサート
        Notification::assertCount(3);
    }
}

特定の「論理テスト」に合格した通知が送信されたことをアサートするために、assertSentToまたはassertNotSentToメソッドへクロージャを渡すこともできます。指定する論理テストに合格する通知が少な​​くとも1つ送信された場合、アサーションは成功します。You may pass a closure to the assertSentTo or assertNotSentTo methods in order to assert that a notification was sent that passes a given "truth test". If at least one notification was sent that passes the given truth test then the assertion will be successful:

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

オンデマンド通知On-Demand Notifications

テストしているコードがオンデマンド通知を送る場合、assertSentOnDemandメソッドにより、そのオンデマンド通知が送られたことをテストできます。If the code you are testing sends on-demand notifications[/docs/{{version}}/notifications#on-demand-notifications], you can test that the on-demand notification was sent via the assertSentOnDemand method:

Notification::assertSentOnDemand(OrderShipped::class);

assertSentOnDemandメソッドの第2引数にクロージャを渡し、オンデマンド通知が正しい「ルート(route)」アドレスへ送られたかを判定できます。By passing a closure as the second argument to the assertSentOnDemand method, you may determine if an on-demand notification was sent to the correct "route" address:

Notification::assertSentOnDemand(
    OrderShipped::class,
    function ($notification, $channels, $notifiable) use ($user) {
        return $notifiable->routes['mail'] === $user->email;
    }
);

Queue FakeQueue Fake

Queueファサードのfakeメソッドを使用して、キュー投入するジョブをキュー投入しないでおくことができます。ほとんどの場合、キュー投入するジョブ自体は別のテストクラスでテストされる可能性が高いため、Laravelが特定のジョブをキューへ投入するように指示したことをアサートするだけで十分です。You may use the Queue facade's fake method to prevent queued jobs from being pushed to the queue. Most likely, it is sufficient to simply assert that Laravel was instructed to push a given job to the queue since the queued jobs themselves may be tested in another test class.

Queueファサードのfakeメソッドを呼び出した後、アプリケーションがジョブをキューに投入しようとしたことをアサートできます。After calling the Queue facade's fake method, you may then assert that the application attempted to push jobs to the queue:

<?php

namespace Tests\Feature;

use App\Jobs\AnotherJob;
use App\Jobs\FinalJob;
use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;

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

        // 注文の実行コード…

        // ジョブまったく投入されなかったことをアサート
        Queue::assertNothingPushed();

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

        // ジョブが2回投入されたことをアサート
        Queue::assertPushed(ShipOrder::class, 2);

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

特定の「論理テスト」に合格するジョブが投入されたことをアサートするために、assertPushedまたはassertNotPushedメソッドにクロージャを渡すこともできます。指定する論理テストに合格するジョブが少なくとも1つ投入された場合、アサートは成功します。You may pass a closure to the assertPushed or assertNotPushed methods in order to assert that a job was pushed that passes a given "truth test". If at least one job was pushed that passes the given truth test then the assertion will be successful:

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

もし、特定のジョブだけをfakeし、他のジョブは通常通り実行させたい場合は、fakeメソッドにfakeするジョブのクラス名を渡します。If you only need to fake specific jobs while allowing your other jobs to execute normally, you may pass the class names of the jobs that should be faked to the fake method:

public function test_orders_can_be_shipped()
{
    Queue::fake([
        ShipOrder::class,
    ]);

    // 注文の発送処理の実行…

    // ジョブが2回キュー投入されることをアサート
    Queue::assertPushed(ShipOrder::class, 2);
}

ジョブチェーンJob Chains

QueueファサードのassertPushedWithChainメソッドとassertPushedWithoutChainメソッドを使用して、投入したジョブのジョブチェーンを検査できます。assertPushedWithChainメソッドは、最初の引数にプライマリジョブをとり、2番目の引数としてチェーンジョブの配列を取ります。The Queue facade's assertPushedWithChain and assertPushedWithoutChain methods may be used to inspect the job chain of a pushed job. The assertPushedWithChain method accepts the primary job as its first argument and an array of chained jobs as its second argument:

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

Queue::assertPushedWithChain(ShipOrder::class, [
    RecordShipment::class,
    UpdateInventory::class
]);

上記の例でわかるように、チェーンジョブの配列はジョブのクラス名の配列です。ただし、実際のジョブインスタンスの配列を提供することもできます。そうすることで、Laravelは、ジョブインスタンスが同じクラスであり、アプリケーションがディスパッチしたチェーンジョブと同じプロパティ値を持つことを保証します。As you can see in the example above, the array of chained jobs may be an array of the job's class names. However, you may also provide an array of actual job instances. When doing so, Laravel will ensure that the job instances are of the same class and have the same property values of the chained jobs dispatched by your application:

Queue::assertPushedWithChain(ShipOrder::class, [
    new RecordShipment,
    new UpdateInventory,
]);

assertPushedWithoutChainメソッドを使用して、ジョブチェーンなしでジョブが投入されたことをアサートできます。You may use the assertPushedWithoutChain method to assert that a job was pushed without a chain of jobs:

Queue::assertPushedWithoutChain(ShipOrder::class);

Storage FakeStorage Fake

Storageファサードのfakeメソッドを使用すると、偽のディスクを簡単に生成できます。これをIlluminate\Http\UploadedFileクラスのファイル生成ユーティリティと組み合わせると、ファイルアップロードのテストが大幅に簡素化できます。例をご覧ください。The Storage facade's fake method allows you to easily generate a fake disk that, combined with the file generation utilities of the Illuminate\Http\UploadedFile class, greatly simplifies the testing of file uploads. For example:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_albums_can_be_uploaded()
    {
        Storage::fake('photos');

        $response = $this->json('POST', '/photos', [
            UploadedFile::fake()->image('photo1.jpg'),
            UploadedFile::fake()->image('photo2.jpg')
        ]);

        // ひとつ以上のファイルが保存されたことをアサート
        Storage::disk('photos')->assertExists('photo1.jpg');
        Storage::disk('photos')->assertExists(['photo1.jpg', 'photo2.jpg']);

        // ひとつ以上のファイルが保存されなかったことをアサート
        Storage::disk('photos')->assertMissing('missing.jpg');
        Storage::disk('photos')->assertMissing(['missing.jpg', 'non-existing.jpg']);

        // 指定したディレクトリが空であることをアサート
        Storage::disk('photos')->assertDirectoryEmpty('/wallpapers');
    }
}

fakeメソッドはデフォルトで、一時ディレクトリにあるすべてのファイルを削除します。これらのファイルを残しておきたい場合は、代わりにpersistentFakeメソッドを使用してください。ファイルアップロードのテストの詳細は、ファイルアップロードに関するHTTPテストドキュメントの情報を参照してください。By default, the fake method will delete all files in its temporary directory. If you would like to keep these files, you may use the "persistentFake" method instead. For more information on testing file uploads, you may consult the HTTP testing documentation's information on file uploads[/docs/{{version}}/http-tests#testing-file-uploads].

warning Warning! imageメソッドには、GD拡張が必要です。Warning
The image method requires the GD extension[https://www.php.net/manual/en/book.image.php].

時間操作Interacting With Time

テスト時、nowIlluminate\Support\Carbon::now()のようなヘルパが返す時間を変更したいことはよくあります。幸いなことに、Laravelのベース機能テストクラスは現在時間を操作するヘルパを用意しています。When testing, you may occasionally need to modify the time returned by helpers such as now or Illuminate\Support\Carbon::now(). Thankfully, Laravel's base feature test class includes helpers that allow you to manipulate the current time:

use Illuminate\Support\Carbon;

public function testTimeCanBeManipulated()
{
    // 未来へ移行する
    $this->travel(5)->milliseconds();
    $this->travel(5)->seconds();
    $this->travel(5)->minutes();
    $this->travel(5)->hours();
    $this->travel(5)->days();
    $this->travel(5)->weeks();
    $this->travel(5)->years();

    // 時間を止め、クロージャ実行後、通常時刻へ戻す
    $this->freezeTime(function (Carbon $time) {
        // ...
    });

    // 過去へ移行する
    $this->travel(-5)->hours();

    // 特定の時間へ移行する
    $this->travelTo(now()->subHours(6));

    // 現在時刻へ戻る
    $this->travelBack();
}

章選択

設定

明暗テーマ
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のみ表示
和文変換

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

本文フォント

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

コードフォント

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

保存内容リセット

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

ヘッダー項目移動

キーボード操作