phplaraveltestingphpunitlaravel-lighthouse

Mocking an uploaded file with content


I'm working on a Laravel project that utilizes GraphQL with Lighthouse for the backend API. For some of the endpoints, we have file upload support. We have successfully tested that.

The new endpoint that we are creating right now, will also support a file upload. But instead of just storing the file somewhere on our server, we have to read the contents of this file and do something depending on this content.

We want to test this new feature, ofcourse. But to do that. We have to mock an uploaded file, with specific contents, to test this. All I could find was just a fake UploadedFile::fake() method that creates a random/empty file for you.

I know I could create unit tests for this. But I really want to add an end-to-end test.

The official lighthouse docs has the following code example:

<?php

$this->multipartGraphQL(
    [
        'operations' => /* @lang JSON */
            '
            {
                "query": "mutation Upload($file: Upload!) { upload(file: $file) }",
                "variables": {
                    "file": null
                }
            }
        ',
        'map' => /* @lang JSON */
            '
            {
                "0": ["variables.file"]
            }
        ',
    ],
    [
        '0' => UploadedFile::fake()->create('image.jpg', 500),
    ]
)

I need to replace that uploaded file with a mock that I created myself. Maybe something like:

<?php

UploadedFile::fake()
    ->fromPath('example/file/in/my/testsuite.obj')
    ->create()

Is there any build-in way I can set the content of a fake uploaded file? Or is there any way I can extend the class with my own factory logic?


Solution

  • To fake a file in Laravel based on test file you can use new File. The class is Illuminate\Http\File.

    The constructor takes a path and gives you a file from that file path. So to use your example, the fake file would be created the following way

    new File('example/file/in/my/testsuite.obj')
    

    You then just need to set the file you sent to Lighthouse to that file.