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

rslanzi's avatar
Level 33

How to test HTTP attach() with a faker uploaded file

I have a method on a controller that receive a file upload and then retransmits via HTTP Client to an external post API route. It works but I'm unable to test it properly: when I retrive to get the fake storage file (with Storage::get()) I obtain an empty string and so the attach() method on the HTTP call fails with this error: InvalidArgumentException: A 'contents' key is required

This is my controller's method:

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use App\Http\Requests\StoreRequest;

public function store(StoreRequest $request) {
    $data = [
        'name' => $request->name,
        // ...
    ];
    
    $response = Http::withToken( $this->token );

    if ($request->hasFile('file')) {
        $file = date('Ymd') . '-file.' . $request->file->extension();
        $request->file->storeAs('files', $file);

        if (Storage::exists("files/$file")) {
            dump(Storage::get("files/$file")); // -> enter on if but empty string on test
            $response = $response->attach('file', Storage::get("files/$file"), $file);
        }
    }

    $response = $response->post($this->endpoint, $data);

    if ($response->successful()) {
        return redirect()->route('thankyou');
    }
}

and this is my test:

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;

/** @test */
public function check_that_store_works()
{
    Storage::fake();
    Http::fake();

    $data = [
        'name' => $this->faker->firstName,
        'file' => UploadedFile::fake()->create('file.pdf'),
    ];
    $file = date('Ymd') . '-file.pdf';

    $this->post( route('files.store'), $data )
        ->assertRedirect( route('thankyou') );

    Storage::assertExists( "files/$file" );
}
0 likes
2 replies
neilstee's avatar

@rslanzi from your controller, the file input is named file not cv like in your test.

Also, the generated date using date('Ymd') from your controller will be different from your test (basically you are running 2 different date('Ymd')) so it won't match any of the files.

rslanzi's avatar
Level 33

Sorry, I tried simplifying my real controller just for the example but left some typos. But the problem is another. ;-)

PS: if I use the get instead of exists, the problem was solved... but it's a workaround that I don't like

if (Storage::get("files/$file") !== "") {
    $response = $response->attach('file', Storage::get("files/$file"), $file);
}

Please or to participate in this conversation.