Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

alhoqbani's avatar

Changing default disk for testing.

I'm trying to build a test for images handling in my application. For the database testing I'm using DatabaseMigrations, so the test persists records in sqlite memory and then discard them after the test.

Is there a way to achieve equivalent results when testing file handling (uploading and deleting files).

Right now I'm using the fake method as suggested per the docs:

        Storage::fake('avatars');

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

        // Assert the file was stored...
        Storage::disk('avatars')->assertExists('avatar.jpg');

        // Assert a file does not exist...
        Storage::disk('avatars')->assertMissing('missing.jpg');

However in my Image model, i'm overriding the delete() method to delete the file linked to the record:

    public function delete()
    {
        Storage::delete($this->image_path);

        return parent::delete();
    }

When testing this method, it will always fail because this method will delete files only from the default storage, but not from the fake storage ('avatars').

Here is my test:

/** @test */
    public function deleted_image_from_db_will_delete_the_file()
    {
        Storage::fake('avatars');
        $file = UploadedFile::fake()->image('avatar.png');
        $image = Image::fromForm($file);  // Store the image and set image_path;
        $image->product_id = 1;
        $image->save();

        Storage::disk('avatars')->assertExists($image->image_path);
        $image->delete();
        Storage::disk('avatars')->assertMissing($image->image_path);
    }

Is it possible to set the default disk for testing to a fake storage?

0 likes
4 replies
alhoqbani's avatar

I think I found a workaround for this issue:

I changed the default disk in config/filesystems.php

'default' => env('DISK_TESTING', 'local'),

and in phpunit.xml added this line:

<env name="DISK_TESTING" value="avatars"/>

finally, in tests/TestCase.php

    protected function setUp()
    {
        parent::setUp();
        // Create The fake Disk
        Storage::fake('avatars');
    }
4 likes
njxqlus's avatar

You can simply add to phpunit.xml next line:

<env name="FILESYSTEM_DRIVER" value="avatars"/>

And better use UploadedFile::fake()->create() instead UploadedFile::fake()->image()

2 likes
adelynx's avatar

I tried both solutions doesn't work. I am using Laravel 5.8.31

marcusmyers's avatar

@adelynx After just running into this situation myself here is what I discovered. When using Storage::fake('avatars') it will successfully create testing disk folder in storage/framework/testing/disks/. Depending on how you are storing your upload will depend on what you use for your test path. Check out example below.


public function test_user_can_edit_their_profile_picture()
{
    Storage::fake('avatars') // storage/framework/testing/disks/avatars/
    $file = UploadedFile::fake()->image('avatar.jpg');
    $user = factory(User::class)->create();

    $response = $this->actingAs($user)->put('/profile/'.$user->id, [ 'photo' => $file]);

    // The file should be in storage/framework/testing/disks/avatars/public/
    // based on how the file is being stored in the controller.
    Storage::disk('avatars')->assertExists('public/'.$file->hashName());
}

Excerpt from Controller

if($request->hasFile('photo')) {
        $user->photo = $request->file('photo')->store('public');
 }

So if in your app you have a Storage Disk called avatars and you are testing it the path for testing will be whatever disk you are storing the file in your controller.

I hope this helps and it wasn't too wordy.

2 likes

Please or to participate in this conversation.