How to test file upload with laravel and phpunit?

前端 未结 6 1891
名媛妹妹
名媛妹妹 2020-12-11 14:32

I\'m trying to run this functional test on my laravel controller. I would like to test image processing, but to do so I want to fake image uploading. How do I do this? I fou

相关标签:
6条回答
  • 2020-12-11 15:12

    With phpunit you can attach a file to a form by using attach() method.

    Example from lumen docs:

    public function testPhotoCanBeUploaded()
    {
        $this->visit('/upload')
             ->name('File Name', 'name')
             ->attach($absolutePathToFile, 'photo')
             ->press('Upload')
             ->see('Upload Successful!');
    }
    
    0 讨论(0)
  • 2020-12-11 15:13

    Docs for CrawlerTrait.html#method_action reads:

    Parameters
    string $method
    string $action
    array $wildcards
    array $parameters
    array $cookies
    array $files
    array $server
    string $content

    So I assume the correct call should be

    $response = $this->action(
        'POST',
        'FileStorageController@store',
        [],
        $values,
        [],
        ['file' => $uploadedFile]
    );
    

    unless it requires non-empty wildcards and cookies.

    0 讨论(0)
  • 2020-12-11 15:15

    The best and Easiest way : First Import the Necessary things

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

    Then make a fake file to upload.

    Storage::fake('local');
    $file = UploadedFile::fake()->create('file.pdf');
    

    Then make a JSON Data to pass the file. Example

    $parameters =[
                'institute'=>'Allen Peter Institute',
                'total_marks'=>'100',
                'aggregate_marks'=>'78',
                'percentage'=>'78',
                'year'=>'2002',
                'qualification_document'=>$file,
            ];
    

    Then send the Data to your API.

    $user = User::where('email','candidate@fakemail.com')->first();
    
    $response = $this->json('post', 'api/user', $parameters, $this->headers($user));
    
    $response->assertStatus(200);
    

    I hope it will work.

    0 讨论(0)
  • 2020-12-11 15:16

    Add similar setUp() method into your testcase:

    protected function setUp()
    {
        parent::setUp();
    
        $_FILES = array(
            'image'    =>  array(
                'name'      =>  'test.jpg',
                'tmp_name'  =>  __DIR__ . '/_files/phpunit-test.jpg',
                'type'      =>  'image/jpeg',
                'size'      =>  499,
                'error'     =>  0
            )
        );
    }
    

    This will spoof your $_FILES global and let Laravel think that there is something uploaded.

    0 讨论(0)
  • 2020-12-11 15:19

    For anyone else stumbling upon this question, you can nowadays do this:

        $response = $this->postJson('/product-import', [
            'file' => new \Illuminate\Http\UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, null, true),
        ]);
    
    0 讨论(0)
  • 2020-12-11 15:21

    Here is a full example how to test with custom files. I needed this for parsing CSV files with known format so my files had to had exact formatting and contents. If you need just images or random sized files use $file->fake->image() or create() methods. Those come bundled with Laravel.

    namespace Tests\Feature;
    
    use Tests\TestCase;
    use Illuminate\Http\UploadedFile;
    use Illuminate\Support\Facades\Storage;
    
    class PanelistImportTest extends TestCase
    {
        /** @test */
        public function user_should_be_able_to_upload_csv_file()
        {
            // If your route requires authenticated user
            $user = Factory('App\User')->create();
            $this->actingAs($user);
    
            // Fake any disk here
            Storage::fake('local');
    
            $filePath='/tmp/randomstring.csv';
    
            // Create file
            file_put_contents($filePath, "HeaderA,HeaderB,HeaderC\n");
    
            $this->postJson('/upload', [
                'file' => new UploadedFile($filePath,'test.csv', null, null, null, true),
            ])->assertStatus(200);
    
            Storage::disk('local')->assertExists('test.csv');
        }
    }
    

    Here is the controller to go with it:

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Illuminate\Support\Facades\Storage;
    
    class UploadController extends Controller
    {
        public function save(Request $request)
        {
            $file = $request->file('file');
    
            Storage::disk('local')->putFileAs('', $file, $file->getClientOriginalName());
    
            return response([
                'message' => 'uploaded'
            ], 200);
        }
    }
    
    0 讨论(0)
提交回复
热议问题