Unable to find a file at path. Failed asserting that false is true

Viewed 252

I have written a test that checks if a user is able to upload a file. I use public as my mocking disk. This is my test:

public function testUserCanUploadFile()
    {
        $this->withoutExceptionHandling();
        $this->signIn();

        Storage::fake('/public'); //Mock a disk
        $file = UploadedFile::fake()->image('test.jpg'); //Upload a fake image.

        $assortmentAttributes = Assortment::factory()->raw(); // Use the assortment factory.
        $assortmentAttributes['image'] = $file; // Add a additional field in the assortment factory.

        $this->post(route('assortments.store'), $assortmentAttributes)->assertRedirect(); // Post the fields to the assortmentcontroller store method.
        Storage::disk('/public')->assertExists($file); // Check if the field exists.

    }

I have also written code in my controller that makes sure that the file is saved. This is the code in my controller:

 public function store(Request $request)
    {     
Assortment::create([
             'file' => $request->file('image')->store('file', '/public'),
             'user_id' => $user->id,
             'category_id' => $assortment->category->id,
             'title' => $assortment->title,
             'description' => $assortment->description
         ]);
 
         if ($request->wantsJson()) {
             return response([], 204);
        }

        return redirect()->route('assortments.show', $assortment->slug)
                        ->with('success','Verzameling is succesvol aangemaakt.');

        
    }

When I run the test I get: Unable to find a file at path. Failed asserting that false is true. I know that this is caused because the controller generates another random file then the one I wanted in my test. But how do I fix this? I have no idea.

I also used assertExist($file->hashName()) in my test. But I deleted that since it gave the same error.

How do I solve this error?

2 Answers

I think the problem is:

'file' => $request->file('image')->store('file', '/public')

the first parameter for store() function is path, and the second one is disk. So your file must be saved in /file/test.jpg, yet your test is trying to find /test.jpg

Second parameter to the store() should be the name of a storage disk configured in the config/filesystems.php. While the statement in store method is having a path.

public function store(Request $request)
{     
    Assortment::create([
        'file' => $request->file('image')->store('file', 'public'),    //changed here
        'user_id' => $user->id,
        'category_id' => $assortment->category->id,
        'title' => $assortment->title,
        'description' => $assortment->description
    ]);
 
    if ($request->wantsJson()) {
        return response([], 204);
    }

    return redirect()->route('assortments.show', $assortment->slug)
        ->with('success','Verzameling is succesvol aangemaakt.');
        
}

Similarly the parameter passed to disk() should be the name of one of the storage disk configured in config/filesystems.php

public function testUserCanUploadFile()
{
    $this->withoutExceptionHandling();
    $this->signIn();

    //Mock a disk
    Storage::fake('public');     //changed here from /public to public

    //Upload a fake image.
    $file = UploadedFile::fake()->image('test.jpg'); 

    // Use the assortment factory.
    $assortmentAttributes = Assortment::factory()->raw(); 

    // Add a additional field to the attributes
    $assortmentAttributes['image'] = $file; 


    // Post the fields to the assortmentcontroller store method.
    $this->post(route('assortments.store'), $assortmentAttributes)->assertRedirect();
 

    // Check if the field exists.
    Storage::disk('public')->assertExists('/file/' . $file->hashName());     //changed here

}
Related