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

GimmeMylanta's avatar

Call to a member function store() on string when testing uploads

Hey Guys,

I'm having real issues testing my file upload functionality, I just cant seem to get it to work.

In my controller i have the following code;

if ($request->hasFile('filename')) {
    foreach ($request->file('filename') as $image) {
        if ($upload = $image->store('images', 'public')) {
            $filename = $upload;
            // more logic here
        }
    }
}

This works fine for uploading files on my frontend, but my test is failing. My test looks like so;

Storage::fake('public');

$this->postJson('/api/upload', [
    'filename' => $image = UploadedFile::fake()->image('fakeimage.jpg')
]);

Storage::disk('public')->assertExists("images/{$image->hashName()}");
Storage::disk('public')->assertMissing('images/missing.jpg');

The error im seeing is as follows;

Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function store() on string

I have no idea why this would work on the frontend, but fail on the test.

Any help would be greatly appreciated.

0 likes
12 replies
jeffreyvanrossum's avatar

You are doing a foreach on filename, does this mean you are handling multiple files?

In your test you are only submitting one file.

jeffreyvanrossum's avatar

I think you'll have to make sure that your filename property in your test is an array in that case.

GimmeMylanta's avatar

@jeffreyvanrossum I changed it to filename[] and am now getting the following error; Unable to find a file at path [images/doBjcK4HfOkapmqDtEsGXMPj3ujf0tOp5L2NdcEQ.jpeg]

@sti3bas its still returning the same error

jeffreyvanrossum's avatar

Just to be sure, have you checked if your files are stored in the storage/public/images directory?

jeffreyvanrossum's avatar

It might have something to do with the file extension. You created an image with jpg not jpeg. I think test fails because of that.

GimmeMylanta's avatar

@jeffreyvanrossum I thought that as well, but the store method creates a unique filename which is assigned, so that doesn't seem to be the case ... So frustrating

psylogic's avatar

would you try this one

$this->call('post','/api/upload', [],[],$photos);

using call instead of jsonPost

$photos = [
'filename' => [
    UploadedFile::fake()->image('fakeimage.jpg'),
    UploadedFile::fake()->image('fakeimage2.jpg')
  ]
];

$this->call('post','/api/upload', [],[],$photos);

Storage::disk('public')->assertExists("images/{$photos['filename'][0]->hashName()}");

psylogic's avatar
psylogic
Best Answer
Level 7

@chris1981 ;

Here's my code and it pass and please check the status also the URL if it is correct

and you should pass the images as array

'filename' => [
      $image = UploadedFile::fake()->image('fakeimage.jpg')
      ]

api.php

Route::post('/upload', 'TestController');

Controller

public function __invoke(Request $request)
    {
        if ($request->hasFile('filename')) {
            foreach ($request->file('filename') as $image) {
                if ($upload = $image->store('images', 'public')) {
                    return  response()->json($upload, 201);
                }else{
                    return  response()->json("no", 403);
                }
            }
        }
    }

Test

public function testExample()
    {
        // to track the errors
        // $this->withoutExceptionHandling();


        Storage::fake('public');

        $this->postJson('/api/upload', [
            'filename' => [
                $image = UploadedFile::fake()->image('fakeimage.jpg')
                ]
        ])
        ->assertStatus(201);

        Storage::disk('public')->assertExists("images/".$image->hashName());
        Storage::disk('public')->assertMissing('images/missing.jpg');
    }
GimmeMylanta's avatar

@psylogic Ohhhhhhhhhhhh ...... My 'filename' in the test wasn't enclosed in an array ... It works perfect now! .... Thank you so much

1 like

Please or to participate in this conversation.