Mock file in Storage to download in Laravel

11,259

Solution 1

I might be late here. but wanted to help others visiting this question to give an idea of implementing it.

Here is a sample with some assertions.

<?php

namespace Tests\Feature\Upload;

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class SampleDownloadTest extends TestCase
{
    /**
     * @test
     */
    public function uploaded_file_downloads_correctly()
    {
        //keep a sample file inside projectroot/resources/files folder
        //create a file from it
        $exampleFile = new File(resource_path('files/test-file.png'))
        //copy that file to projectroot/storage/app/uploads folder
        Storage::putFileAs('/uploads', $exampleFile, 'test-file.png');

        //make request to file download url to get file 
        $response = $this->get("/files/file/download/url");

        //check whethe response was ok
        $response->assertOk();
        $response->assertHeader('Content-Type', 'image/png')
        //check whether file exists in path
        Storage::assertExists('/uploads/test-file.png');
        //do some more assertions.....
        //after test delete the file from storage path
        Storage::delete('uploads/test-file.png');
        //check whether file was deleted
        Storage::assertMissing('/uploads/test-file.png');
    }
}

Solution 2

You could just create a new file directly or copy a specific test file for example:

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// for simple text files or if the content doesn't matter
Storage::disk('avatars')->put('avatar.jpg', 'some non-jpg content');

// if you need a specific file for your test
$file = new File(base_path('tests/resources/avatar.jpg'));
Storage::disk('avatars')->putFileAs('/', $file, 'avatar.jpg');

The latter function will take the $file and copy it under the given name avatar.jpg to the given directory / on the disk avatars. You can read more about it in the official documentation.

Share:
11,259
Sheph
Author by

Sheph

Updated on July 04, 2022

Comments

  • Sheph
    Sheph almost 2 years

    Is there a way to mock a file using Laravels Storage::fake() method?

    I have used https://laravel.com/docs/5.7/mocking#storage-fake as a base for my tests, which works fine for uploads. But my download tests are ugly as I have to run my upload route first every time with a mock upload UploadedFile::fake()->image('avatar.jpg'). Is there a way to skip that part and mock the file to exist directly in the fake storage system?

    public function testAvatarUpload()
    {
        Storage::fake('avatars');
    
        // This is the call I would like to change into a mocked existing uploaded file
        $uploadResponse = $this->json('POST', '/avatar', [
            'avatar' => UploadedFile::fake()->image('avatar.jpg')
        ]);
    
        // Download the first avatar
        $response = $this->get('/download/avatar/1');
    
        $response->assertStatus(200);
    }