2015-10-22 8 views
13

Ich versuche diesen Funktionstest auf meinem Laravel-Controller auszuführen. Ich möchte die Bildverarbeitung testen, aber dazu möchte ich das Hochladen von Bildern vortäuschen. Wie mache ich das? Ich habe ein paar Beispiele online gefunden, aber keine scheint für mich zu funktionieren. Hier ist, was ich habe:Wie testet man Datei-Upload mit Laravel und PHP-Unit?

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

Aber der Controller diese Prüfung nicht bestanden bekommt:

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

also irgendwie die Datei nicht korrekt übergeben. Wie gehe ich vor?


aktualisieren

Basierend auf max.lanin des suggestin, ich habe 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 existiert und die Größe ist korrekt.

+0

ich sehen Sie dies in den Testmodus gesetzt haben. Ist die hochgeladene Datei größer als die maximale Dateigröße in php.ini? –

+0

Nein, das ist es nicht, Upload-Limit ist 2 MB, Testdatei ist 300 KB. –

Antwort

9

Docs for CrawlerTrait.html#method_action liest:

Parameter
string $ Methode
string $ Aktion
Array $ Platzhalter
Array $ Parameter
Array $ Cookies
Array $ Dateien
Array $ server
Zeichenfolge $ Inhalt

Also gehe ich davon aus dem richtigen Anruf

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

sein soll, wenn es nicht leere Platzhalter und Cookies erforderlich.

Als eine Randnotiz ist es auf keinen Fall ein Einheit Test.

+0

Versuchen Sie Ihren Vorschlag. Test Jargon scheint so vage zu mir: p Welche Art von Test wäre das? –

+1

@ JasperKennis, es ist kein Jargon, sondern eine Terminologie, die Leuten hilft, auf der gleichen Seite zu bleiben und Dinge zu diskutieren. Der Missbrauch der Terminologie verwirrt und macht das Gegenteil. Was Sie tun, ist entweder Funktions- oder Integrationstest, abhängig von den Absichten. In der Regel thumbnail, Unit-Test überprüft imperativen Teil, dh Logik einer einzelnen Klasse, alles (sinnvoll) sonst verspotten.Integration Tests überprüft deklarativen Teil, dh Konfigurationen, Vorlagen, etc. Funktionstests prüft die Funktionalität der Anwendung wie in der Spezifikation definiert –

+0

Das hat funktioniert ^^ Der Test scheitert immer noch, aber es kommt über den angegebenen Punkt hinaus, an dem ich feststeckte Hinweis: Ich benutze Laravel 4.2 und das nicht Nimm das Argument '$ Wildcards'. –

4

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

Beispiel von lumen docs:

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

Das hilft nicht, ich teste Controller-Antworten mit der'Aktion'-Methode. Dies ist ein Beispiel auf höherer Ebene. –

0

In ähnlicher setUp() Methode in Ihre Testfall:

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

Dies wird Ihre $ fälschen _files global und lassen Laravel denken, dass es etwas hochgeladen ist.

+0

Ich habe dies versucht, beide benennen die Datei 'image' oder' file', aber die Prüfung schlägt immer noch fehl. Soll das mit der Testeinheit '-> action' Methode funktionieren? –

+0

Haben Sie die tatsächliche Größe und den Pfad der Datei zum Array hinzugefügt? Versuchen Sie auch, die Zeilen zu wechseln, so dass das parent :: setUp nach dem Spoof Ihres $ _FILES-Arrays ist. –

+0

Ich aktualisierte meine Frage, um das auch zu reflektieren, aber nein, es hat nicht geholfen :(Dateiname und Größe sind korrekt. –

3

Für alle anderen auf diese Frage zu stolpern, können Sie dies jetzt 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), 
    ]); 
+0

Für Beitrag füge ich den Konstruktor '__construct ($ Pfad, $ OriginalName, $ MimeType = null, $ Größe = null, $ Fehler = null, $ Test = falsch)', die von oben genannten Code aufgerufen wird. Es funktioniert hervorragend mit Bildern und PDFs in meinen Komponententests. – barfoos

0

Hier ist ein vollständiges Beispiel, wie mit benutzerdefinierten Dateien zu testen. Ich brauchte das für das Parsen von CSV-Dateien mit bekanntem Format, so dass meine Dateien genaue Formatierung und Inhalt hatten. Wenn Sie nur Bilder oder Dateien in zufälliger Größe benötigen, verwenden Sie die Methoden $ file-> fake-> image() oder create(). Diese kommen zusammen mit 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'); 
    } 
} 

ist die Steuerung mit ihm zu gehen:

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