Mock file in Storage to download in Laravel
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.
Sheph
Updated on July 04, 2022Comments
-
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); }