The queue test proved the job was pushed. A test that writes a PDF should not touch the disk you use in development. A test that calls a payment provider should not call the provider. Fake the disk and fake HTTP, and fail the test if the code calls a host you did not expect.
Test-driven Laravel · Lesson 3
Faking storage and HTTP
Video
01 Swap both edges before the request
Storage::fake() replaces the default disk. Http::fake() returns the response you describe. preventStrayRequests() makes any other host a failure.
it('stores the pdf after the provider accepts the charge', function () {
Storage::fake();
Http::preventStrayRequests();
Http::fake([
'payments.example/*' => Http::response(['id' => 'pay_1'], 200),
]);
$invoice = Invoice::factory()->issued()->create();
$this->actingAs($invoice->team->owner)
->post('/invoices/'.$invoice->id.'/charge')
->assertRedirect();
Storage::assertExists('invoices/'.$invoice->id.'.pdf');
});Assert the file path the feature promised. Asserting that some file exists is too weak: a bug that writes the wrong name would still pass.
Http::assertSent() is there when the interesting part is the request body, such as the amount. Use it in the test that is about the amount, not in this one.
02 Assert the amount when the amount is the point
The PDF test above only cares that a file landed after a 200. A charge test cares that the provider was asked for this invoice’s total. assertSent() receives the request. A wrong amount fails here, and a stray host still fails because preventStrayRequests() is on.
it('charges the invoice total', function () {
Http::preventStrayRequests();
Http::fake([
'payments.example/*' => Http::response(['id' => 'pay_1'], 200),
]);
$invoice = Invoice::factory()->issued()->create(['total' => 2400]);
$this->actingAs($invoice->team->owner)
->post('/invoices/'.$invoice->id.'/charge')
->assertRedirect();
Http::assertSent(function ($request) {
return $request->url() === 'https://payments.example/charges'
&& $request['amount'] === 2400;
});
});Fake the sequence you mean. A 500 from the provider is a different test, and it should assert the invoice was not marked paid. This one asserts the body of the request that should have gone out.
Storage::fake() without an argument replaces the default disk from filesystems.php. If the PDF is written to a disk named invoices, pass that name: Storage::fake('invoices'). An assertion against the default disk then passes while the file landed somewhere else, which is the bug the path check was meant to catch.
Recap
You can store a PDF on a fake disk and refuse any HTTP host the test did not describe.
Storage::fake()replaces the disk. Assert the path the feature promised.Http::preventStrayRequests()fails the test on a host you did not fake.assertSent()belongs in the test that is about the amount, not in the test that only cares the file exists.
Check yourself · 3 questions
Question 1 of 3The code writes the PDF to the wrong filename. Storage::assertExists() is not called, and the test only checks that the disk is non-empty. What passes?