drewdan's avatar
Level 15

Faking a File Upload

Hi All,

Im having a few issues with faking an image upload.

In my controller I have the following

if (isset($data['emailCustomisation'])) {
$emailCustomisation = new EmailCustomisation();     
$emailCustomisation->logo = $request
                ->file('emailCustomisation.logo')
                ->store('logos', config('filesystems.cloud'));
$emailCustomisation->company_id = $company->id;
$emailCustomisation->color = $data['emailCustomisation']['color'];
$emailCustomisation->save();

This is the test that I run on the controller, but it always fails

$requestData = [
            'company' => [
                'label' => 'foo',
                'name' => $company->name,
                'home_page' => $company->home_page,
                'phone_number' => $company->phone_number,
                'timezone' => $company->timezone
            ], 
            'emailCustomisation' => [
                'logo' => UploadedFile::fake()->image('avatar.jpg'),
                'color' => $hexColour
            ] 
        ];

It is failing with the error:

Error: Call to a member function store() on null

Does anyone know what may be causing this?

Thanks :)

0 likes
4 replies
devfrey's avatar

How does your test submit the $requestData? Please share that code.

drewdan's avatar
Level 15

@DEVFREY -

$company = $this->companyModel->find(1);

        $hexColour = $this->faker->hexcolor();

        $request = new \Illuminate\Http\Request;

        $requestData = [
            'company' => [
                'label' => 'foo',
                'name' => $company->name,
                'home_page' => $company->home_page,
                'phone_number' => $company->phone_number,
                'timezone' => $company->timezone
            ], 
            'emailCustomisation' => [
                'logo' => UploadedFile::fake()->image('avatar.jpg'),
                'color' => $hexColour
            ] 
        ];

        $request->merge($requestData);

        $response = $this->controller->update($request, $company);

sorry, I should have put that in from the outset! Thanks for reviewing my code :D

devfrey's avatar

@DREWDAN - I suggest you take a look at HTTP Testing in the Laravel documentation. Unit testing your controllers is something I would advise against. I don't think it's a viable testing method.

Your HTTP test could look something like this:

public function test_file_upload()
{
    Storage::fake(); // Important!

    $response = $this->post('/some/endpoint', [
        'emailCustomisation' => [
            'logo' => UploadedFile::fake()->image('avatar.jpg'),
            'color' => $hexColour,
        ],
    ]);

    Storage::assertExists('avatar.jpg');
}
drewdan's avatar
Level 15

@DEVFREY - Thank you for your feedback. Unit vs Feature testing is an ongoing debate in my office, so we are writing tests from both approaches to see which has the best outcome. I think I would be eager to agree with you at this point. Is there a way around my issue performing a Unit Test, or is it something of a dead end?

Please or to participate in this conversation.