Learned today that using Storage::fake() only fakes the default disk… This might not be obvious at first, but it is definitely to be aware of.

Thanks to Jason McCreary from laravelshift.com.

Something else I stumbled on when refactoring Shift's logs to private app storage (storage/app/logs). I did so to remove the coupling between the application and the server. This is a pattern I've followed in the new side-projects, but had lived with this broken window in Shift.

However, testing this proved a bit of a challenge. I assumed Storage::fake() would fake all Storage calls. But it only fakes them for the default disk. In the case of Shift, I was now writing a log file to the local disk and then copying to the s3 disk.

To get the tests passing, I needed to fake both disks. Here's a full example test to ensure the log is sent to S3 even if a Shift fails.

#[Test] > public function it_stores_the_log_and_exit_code_on_error(): void > { > $order = Order::factory()->create(); > > Storage::fake('s3'); > Storage::fake('logs'); > > $content = $this->faker()->md5(); > Storage::disk('logs')->put('shifts/' . $order->id . '.log', $content); > > Process::preventStrayProcesses()->fake(['php *' => 2]); > > try { > PerformShift::dispatch($order); > } catch (ShiftException) { > $order->refresh(); > $this->assertSame(OrderStatus::Hold, $order->status); > $this->assertSame(ExitCode::SystemError, $order->exit_code); > $this->assertNull($order->pull_request_url); > > Storage::disk('s3')->assertExists('logs/' . $order->product->sku . '/' . $order->id . '.log', $content); > } > } > ```