|
24 | 24 | - [Rendering Mailables](#rendering-mailables)
|
25 | 25 | - [Previewing Mailables In The Browser](#previewing-mailables-in-the-browser)
|
26 | 26 | - [Localizing Mailables](#localizing-mailables)
|
27 |
| -- [Testing Mailables](#testing-mailables) |
| 27 | +- [Testing](#testing-mailables) |
| 28 | + - [Testing Mailable Content](#testing-mailable-content) |
| 29 | + - [Testing Mailable Sending](#testing-mailable-sending) |
28 | 30 | - [Mail & Local Development](#mail-and-local-development)
|
29 | 31 | - [Events](#events)
|
30 | 32 | - [Custom Transports](#custom-transports)
|
@@ -929,7 +931,10 @@ Once you have implemented the interface, Laravel will automatically use the pref
|
929 | 931 | Mail::to($request->user())->send(new OrderShipped($order));
|
930 | 932 |
|
931 | 933 | <a name="testing-mailables"></a>
|
932 |
| -## Testing Mailables |
| 934 | +## Testing |
| 935 | + |
| 936 | +<a name="testing-mailable-content"></a> |
| 937 | +### Testing Mailable Content |
933 | 938 |
|
934 | 939 | Laravel provides a variety of methods for inspecting your mailable's structure. In addition, Laravel provides several convenient methods for testing that your mailable contains the content that you expect. These methods are: `assertSeeInHtml`, `assertDontSeeInHtml`, `assertSeeInOrderInHtml`, `assertSeeInText`, `assertDontSeeInText`, `assertSeeInOrderInText`, `assertHasAttachment`, `assertHasAttachedData`, `assertHasAttachmentFromStorage`, and `assertHasAttachmentFromStorageDisk`.
|
935 | 940 |
|
@@ -968,9 +973,98 @@ As you might expect, the "HTML" assertions assert that the HTML version of your
|
968 | 973 | }
|
969 | 974 |
|
970 | 975 | <a name="testing-mailable-sending"></a>
|
971 |
| -#### Testing Mailable Sending |
| 976 | +### Testing Mailable Sending |
| 977 | + |
| 978 | +We suggest testing the content of your mailables separately from your tests that assert that a given mailable was "sent" to a specific user. Typically, the content of mailables it not relevant to the code you are testing, and it is sufficient to simply assert that Laravel was instructed to send a given mailable. |
| 979 | + |
| 980 | +You may use the `Mail` facade's `fake` method to prevent mail from being sent. After calling the `Mail` facade's `fake` method, you may then assert that mailables were instructed to be sent to users and even inspect the data the mailables received: |
| 981 | + |
| 982 | + <?php |
| 983 | + |
| 984 | + namespace Tests\Feature; |
| 985 | + |
| 986 | + use App\Mail\OrderShipped; |
| 987 | + use Illuminate\Support\Facades\Mail; |
| 988 | + use Tests\TestCase; |
| 989 | + |
| 990 | + class ExampleTest extends TestCase |
| 991 | + { |
| 992 | + public function test_orders_can_be_shipped(): void |
| 993 | + { |
| 994 | + Mail::fake(); |
| 995 | + |
| 996 | + // Perform order shipping... |
| 997 | + |
| 998 | + // Assert that no mailables were sent... |
| 999 | + Mail::assertNothingSent(); |
| 1000 | + |
| 1001 | + // Assert that a mailable was sent... |
| 1002 | + Mail::assertSent(OrderShipped::class); |
| 1003 | + |
| 1004 | + // Assert a mailable was sent twice... |
| 1005 | + Mail::assertSent(OrderShipped::class, 2); |
| 1006 | + |
| 1007 | + // Assert a mailable was not sent... |
| 1008 | + Mail::assertNotSent(AnotherMailable::class); |
| 1009 | + } |
| 1010 | + } |
| 1011 | + |
| 1012 | +If you are queueing mailables for delivery in the background, you should use the `assertQueued` method instead of `assertSent`: |
| 1013 | + |
| 1014 | + Mail::assertQueued(OrderShipped::class); |
| 1015 | + |
| 1016 | + Mail::assertNotQueued(OrderShipped::class); |
| 1017 | + |
| 1018 | + Mail::assertNothingQueued(); |
| 1019 | + |
| 1020 | +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: |
972 | 1021 |
|
973 |
| -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 that mailables were sent, check out our documentation on the [Mail fake](/docs/{{version}}/mocking#mail-fake). |
| 1022 | + Mail::assertSent(function (OrderShipped $mail) use ($order) { |
| 1023 | + return $mail->order->id === $order->id; |
| 1024 | + }); |
| 1025 | + |
| 1026 | +When calling the `Mail` facade's assertion methods, the mailable instance accepted by the provided closure exposes helpful methods for examining the mailable: |
| 1027 | + |
| 1028 | + Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($user) { |
| 1029 | + return $mail->hasTo($user->email) && |
| 1030 | + $mail->hasCc('...') && |
| 1031 | + $mail->hasBcc('...') && |
| 1032 | + $mail->hasReplyTo('...') && |
| 1033 | + $mail->hasFrom('...') && |
| 1034 | + $mail->hasSubject('...'); |
| 1035 | + }); |
| 1036 | + |
| 1037 | +The mailable instance also includes several helpful methods for examining the attachments on a mailable: |
| 1038 | + |
| 1039 | + use Illuminate\Mail\Mailables\Attachment; |
| 1040 | + |
| 1041 | + Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) { |
| 1042 | + return $mail->hasAttachment( |
| 1043 | + Attachment::fromPath('/path/to/file') |
| 1044 | + ->as('name.pdf') |
| 1045 | + ->withMime('application/pdf') |
| 1046 | + ); |
| 1047 | + }); |
| 1048 | + |
| 1049 | + Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) { |
| 1050 | + return $mail->hasAttachment( |
| 1051 | + Attachment::fromStorageDisk('s3', '/path/to/file') |
| 1052 | + ); |
| 1053 | + }); |
| 1054 | + |
| 1055 | + Mail::assertSent(OrderShipped::class, function (OrderShipped $mail) use ($pdfData) { |
| 1056 | + return $mail->hasAttachment( |
| 1057 | + Attachment::fromData(fn () => $pdfData, 'name.pdf') |
| 1058 | + ); |
| 1059 | + }); |
| 1060 | + |
| 1061 | +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: |
| 1062 | + |
| 1063 | + Mail::assertNothingOutgoing(); |
| 1064 | + |
| 1065 | + Mail::assertNotOutgoing(function (OrderShipped $mail) use ($order) { |
| 1066 | + return $mail->order->id === $order->id; |
| 1067 | + }); |
974 | 1068 |
|
975 | 1069 | <a name="mail-and-local-development"></a>
|
976 | 1070 | ## Mail & Local Development
|
|
0 commit comments