it-swarm.com.de

Wie teste ich den Datei-Upload mit Laravel und Phpunit?

Ich versuche diesen Funktionstest mit meinem Laravel-Controller durchzuführen. Ich möchte die Bildverarbeitung testen, aber dafür möchte ich das Hochladen von Bildern fälschen. Wie mache ich das? Ich habe ein paar Beispiele online gefunden, aber es scheint, dass keiner für mich funktioniert. Folgendes habe ich:

public function testResizeMethod()
{
    $this->prepareCleanDB();

    $this->_createAccessableCompany();

    $local_file = __DIR__ . '/test-files/large-avatar.jpg';

    $uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile(
        $local_file,
        'large-avatar.jpg',
        'image/jpeg',
        null,
        null,
        true
    );


    $values =  array(
        'company_id' => $this->company->id
    );

    $response = $this->action(
        'POST',
        '[email protected]',
        $values,
        ['file' => $uploadedFile]
    );

    $readable_response = $this->getReadableResponseObject($response);
}

Der Controller bekommt diese Prüfung jedoch nicht bestanden:

elseif (!Input::hasFile('file'))
{
    return Response::error('No file uploaded');
}

Also irgendwie wird die Datei nicht richtig weitergegeben. Wie gehe ich vor?


Update

Basierend auf dem Vorschlag von max.lanin habe ich auch versucht:

public function setUp()
{
    // Tried with parent::setUp() here and at the end
    // parent::setUp();
    $local_file = __DIR__ . '/test-files/large-avatar.jpg';

    print($local_file);

    $_FILES = array(
        'file' => array (
            'tmp_name' => $local_file,
            'name' => 'large-avatar.jpg',
            'type' => 'image/jpeg',
            'size' => 335057,
            'error' => 0,
        ),
        'image' => array (
            'tmp_name' => $local_file,
            'name' => 'large-avatar.jpg',
            'type' => 'image/jpeg',
            'size' => 335057,
            'error' => 0,
        ),
    );

    parent::setUp();
}

aber ohne erfolg. Die verwendete Datei ist vorhanden und die Größe stimmt.

16
Jasper Kennis

Dokumente für CrawlerTrait.html # method_action liest:

Parameter
Zeichenfolge $ -Methode
Zeichenfolge $ action
Array $ Platzhalter
Array $ -Parameter
Array $ Cookies
Array $ Dateien
Array $ Server
Zeichenfolge $ content 

Ich gehe also davon aus, dass der richtige Anruf sein sollte

$response = $this->action(
    'POST',
    '[email protected]',
    [],
    $values,
    [],
    ['file' => $uploadedFile]
);

es sei denn, es sind nicht leere Platzhalter und Cookies erforderlich.

Als Randbemerkung handelt es sich keinesfalls um einen unit -Test.

10
Alex Blex

Für alle anderen, die über diese Frage stolpern, können Sie dies heute tun:

    $response = $this->postJson('/product-import', [
        'file' => new \Illuminate\Http\UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, null, true),
    ]);
6
Mikael

Mit phpunit können Sie eine Datei an ein Formular anhängen, indem Sie die attach () - Methode verwenden.

Beispiel aus Lumen docs :

public function testPhotoCanBeUploaded()
{
    $this->visit('/upload')
         ->name('File Name', 'name')
         ->attach($absolutePathToFile, 'photo')
         ->press('Upload')
         ->see('Upload Successful!');
}
5
Alex Kyriakidis

Hier finden Sie ein vollständiges Beispiel zum Testen mit benutzerdefinierten Dateien. Ich brauchte das zum Analysieren von CSV-Dateien mit bekanntem Format, sodass meine Dateien genaue Formatierungen und Inhalte haben mussten. Wenn Sie nur Bilder oder Dateien in zufälliger Größe benötigen, verwenden Sie die Methoden $ file-> fake-> image () oder create (). Die kommen mit Laravel zusammen.

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');
    }
}

Hier ist der Controller dazu:

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);
    }
}
2
Juha Vehnia

Fügen Sie Ihrem Testfall eine ähnliche setUp()-Methode hinzu:

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
        )
    );
}

Dadurch wird Ihr $ _FILES global gefälscht und Laravel wird der Meinung, dass etwas hochgeladen wurde.

1
Maxim Lanin

Importieren Sie zuerst die notwendigen Dinge

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

Dann machen Sie eine gefälschte Datei zum Hochladen.

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

Dann machen Sie eine JSON-Daten, um die Datei zu übergeben. Beispiel

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

Senden Sie dann die Daten an Ihre API.

$user = User::where('email','[email protected]')->first();

$response = $this->json('post', 'api/user', $parameters, $this->headers($user));

$response->assertStatus(200);

Ich hoffe, dass es funktionieren wird.

1
Inamur Rahman