So testen Sie den Dateiupload in Laravel 5.2

Lesezeit: 4 Minuten

Ich versuche, eine Upload-API zu testen, aber es schlägt jedes Mal fehl:

Testcode:

$JSONResponse = $this->call('POST', '/upload', [], [], [
    'photo' => new UploadedFile(base_path('public/uploads/test') . '/34610974.jpg', '34610974.jpg')
]);

$this->assertResponseOk();
$this->seeJsonStructure(['name']);

$response = json_decode($JSONResponse);
$this->assertTrue(file_exists(base_path('public/uploads') . "https://stackoverflow.com/" . $response['name']));

Dateipfad ist /public/uploads/test/34610974.jpg

Hier ist mein Upload-Code in einem Controller:

$this->validate($request, [
    'photo' => 'bail|required|image|max:1024'
]);

$name="adummyname" . '.' . $request->file('photo')->getClientOriginalExtension();

$request->file('photo')->move('/uploads', $name);

return response()->json(['name' => $name]);

Wie soll ich den Datei-Upload testen? Laravel 5.2? Wie benutzt man call Methode zum Hochladen einer Datei?

Wenn Sie eine Instanz von erstellen UploadedFile den letzten Parameter einstellen $test zu true.

$file = new UploadedFile($path, $name, filesize($path), 'image/png', null, true);
                                                                           ^^^^

Hier ist ein kurzes Beispiel für einen Arbeitstest. Es erwartet, dass Sie einen Stub haben test.png Datei in tests/stubs Mappe.

class UploadTest extends TestCase
{
    public function test_upload_works()
    {
        $stub = __DIR__.'/stubs/test.png';
        $name = str_random(8).'.png';
        $path = sys_get_temp_dir()."https://stackoverflow.com/".$name;

        copy($stub, $path);

        $file = new UploadedFile($path, $name, filesize($path), 'image/png', null, true);
        $response = $this->call('POST', '/upload', [], [], ['photo' => $file], ['Accept' => 'application/json']);

        $this->assertResponseOk();
        $content = json_decode($response->getContent());
        $this->assertObjectHasAttribute('name', $content);

        $uploaded = 'uploads'.DIRECTORY_SEPARATOR.$content->name;
        $this->assertFileExists(public_path($uploaded));

        @unlink($uploaded);
    }
}
➔ phpunit tests/UploadTest.php
PHPUnit 4.8.24 by Sebastian Bergmann and contributors.

.

Time: 2.97 seconds, Memory: 14.00Mb

OK (1 test, 3 assertions)

  • Das sollte funktionieren, tut es aber nicht. $request->file('photo') hat zwar das UploadFile-Objekt, aber $test in diesem Objekt hat seinen Standardwert false. Seltsam, weil die neue UploadedFile den Parameter $test = true hat.

    – schellingerht

    25. April 2016 um 21:04 Uhr


  • Die obige Antwort reicht für > 5.2.14 nicht aus. Die richtige Antwort finden Sie hier: stackoverflow.com/questions/36857800/…

    – schellingerht

    18. Mai 2016 um 18:40 Uhr

  • Es sollte sein $file = new UploadedFile($path, $name, 'image/png', filesize($path), null, true);

    – Hanson

    5. März 2017 um 3:50 Uhr


  • Zum Symfony 4.1 die richtige Implementierung ist $file = new UploadedFile($path, $name, 'image/png', null, true);

    – Fanan Dala

    4. September 2020 um 12:52 Uhr


Benutzer-Avatar
Alessandro Benoit

In Laravel 5.4 können Sie auch verwenden \Illuminate\Http\UploadedFile::fake(). Ein einfaches Beispiel unten:

/**
 * @test
 */
public function it_should_allow_to_upload_an_image_attachment()
{
    $this->post(
        action('AttachmentController@store'),
        ['file' => UploadedFile::fake()->image('file.png', 600, 600)]
    );

    /** @var \App\Attachment $attachment */
    $this->assertNotNull($attachment = Attachment::query()->first());
    $this->assertFileExists($attachment->path());
    @unlink($attachment->path());
}

Wenn Sie einen anderen Dateityp vortäuschen möchten, können Sie ihn verwenden

UploadedFile::fake()->create($name, $kilobytes = 0)

Mehr Informationen direkt auf Laravel-Dokumentation.

  • Aber die Methode create() besteht die Validierung nicht, wenn Sie nur einen bestimmten MIME-Typ wie mp3 fragen…

    – Syl

    26. Juli 2017 um 11:30 Uhr

Benutzer-Avatar
Mahdi mehrabi

Ich denke, das ist der einfachste Weg, es zu tun

$file=UploadedFile::fake()->image('file.png', 600, 600)];  $this->post(route("user.store"),["file" =>$file));

$user= User::first();

//check file exists in the directory
Storage::disk("local")->assertExists($user->file); 

and I think the best way to delete uploaded files in the test is by using tearDownAfterClass static method,
this will delete all uploaded files

use Illuminate\Filesystem\Filesystem;

public static function tearDownAfterClass():void{
        $file=new Filesystem;
        $file->cleanDirectory("storage/app/public/images");
}

The laravel documentation has an answer for when you want to test a fake file. When you want to test using a real file in laravel 6 you can do the following:

namespace Tests\Feature;

use Illuminate\Http\UploadedFile;
use Tests\TestCase;

class UploadsTest extends TestCase
{
    // This authenticates a user, useful for authenticated routes
    public function setUp(): void
    {
        parent::setUp();
        $user = User::first();
        $this->actingAs($user);
    }    

    public function testUploadFile()
    {
        $name="file.xlsx";
        $path="absolute_directory_of_file/" . $name;
        $file = new UploadedFile($path, $name, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null, true);
        $route="route_for_upload";
        // Params contains any post parameters
        $params = [];  $response = $this->call('POST', $route, $params, [], ['upload' => $file]);  $response->assertStatus(200);  } }

Benutzer-Avatar
Mahmoud Zalt

Sie finden diesen Code hier Verknüpfung

Konfiguration

/**
 * @param      $fileName
 * @param      $stubDirPath
 * @param null $mimeType
 * @param null $size
 *
 * @return  \Illuminate\Http\UploadedFile
 */
public static function getTestingFile($fileName, $stubDirPath, $mimeType = null, $size = null)
{
    $file =  $stubDirPath . $fileName;

    return new \Illuminate\Http\UploadedFile\UploadedFile($file, $fileName, $mimeType, $size, $error = null, $testMode = true);
}

Verwendungszweck

    $fileName="orders.csv";
    $filePath = __DIR__ . '/Stubs/';

    $file = $this->getTestingFile($fileName, $filePath, 'text/csv', 2100);

Ordnerstruktur:

- MyTests
  - TestA.php
  - Stubs
    - orders.csv

1312180cookie-checkSo testen Sie den Dateiupload in Laravel 5.2

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy