How to Test File Uploads in Laravel

Laravel makes it really easy to test if a file was uploaded in phpunit. Lets take a look at what it it takes to test for files.

Lets say that we have a method containing the following code that we want to test.

GetFile.php

public function download() {
        // Get the file out of S3
        $file = Storage::disk('s3')
            ->get('/path/to/file.txt');

        // Store the file locally
        Storage::disk('public')
            ->put('/path/to/file.txt', $file);
}

The corresponding test that would provide coverage for that code is the following.

GetFileTest.php

/** @test */
public function remote_file_gets_stored_locally():void 
{        
        Storage::fake('s3');
        Storage::fake('public');

        $file = UploadedFile::fake()->create('/path/to/file.txt', 0);
        Storage::disk('s3')->put('/path/to/file.txt', $file);
        Storage::disk('s3')->assertExists('/path/to/file.txt');

        $getFile = new GetFile();
        $getFile->download();

        Storage::disk('public')->assertExists('/path/to/file.txt');
}

Test a File Transfer From One Disk to Another in Laravel

Fake the Disks

Use the storage facade to fake each disk you need. In this instance its ‘s3’ and ‘public’.

Create a fake file

Use the UploadedFile::class to fake a file UploadedFile::fake()->create(‘/path/to/file.txt’, 0);

Upload the faked file to the faked disk

Storage::disk(‘s3’)->put(‘/path/to/file.txt’, $file);

Run the function that downloads the file

In our instance its

$getFile = new GetFile();
$getFile->download();

Assert the file exists in the new location

Use the storage facade to assert the file exists on the faked local disk

With this process you can write a test in PHPUnit that proves a file gets downloaded from one disk to another in Laravel. You can find more on this topic on the Laravel Documentation https://laravel.com/docs/10.x/filesystem#testing.

© Chris Mcintosh 2024