2015-10-12 6 views
10

Ich schreibe Tests für meine Laravel-Anwendung mit der Codeception-Bibliothek. Ich verwende die Laravel5 module, und habe es mit cleanup konfiguriert, was bedeutet, dass alle Tests innerhalb einer Datenbanktransaktion ausgeführt werden, so dass meine Testdatenbank nicht mit Testdaten gefüllt wird.Testen einer Laravel 5-Route mit einer exists-Regel über Codeception

Einer der Endpunkte I-Tests sind hat die folgenden Validierungsregeln festgelegt dagegen über Formular Anfragen:

public function rules() 
{ 
    return ['user_id' => 'required|exists:users,id']; 
} 

Der Test, den ich geschrieben habe zu diesem Endpunkt werden.Dies ist wie folgt:

public function store(ApiTester $I) 
{ 
    // Create a couple of users 
    $users = factory(\App\Models\User::class, 2)->create(); 

    $I->wantTo('ask someone to be my friend'); 
    $I->authenticateAs($users[0]); 
    $I->sendPOST('users/' . $users[0]->id . '/friendships', [ 
     'user_id' => $users[1]->id 
    ]); 
    $I->seeResponseCodeIs(201); 
} 

Dieser Test schlägt immer fehl. Nach der Untersuchung kann ich sehen, dass es fehlschlägt, weil die Anforderung aufgrund der exists:users,id-Regel die Validierung nicht besteht. Wenn ich die Codeception-Einstellungen so ändere, dass Tests innerhalb einer Transaktion nicht ausgeführt werden, kann der Validator von Laravel die Existenz der zwei Benutzer, die ich zu Beginn meines Tests erstellt habe, erfolgreich sehen und der Test wird bestanden.

Also, meine Frage ist, gibt es eine Möglichkeit, dass ich das Verhalten des Einwickelns jedes meiner Tests in einer Datenbanktransaktion beibehalten kann, und haben Laravel's Validator in der Lage, die Datensätze zu sehen, die ich in meinen Tests erstellen?

+0

Ich habe genau das gleiche Problem jede Hilfe würde geschätzt werden – Fabrizio

+0

Könnten Sie eine Suite-Konfiguration zu Ihrer Frage hinzufügen? – Naktibalda

Antwort

4

Das Problem ist, dass die ursprünglichen Daten in den Datenbanktabellen nicht betroffen sind, wenn die Transaktion nicht festgeschrieben wird. Sie erstellen also innerhalb der Transaktion zwei Benutzer, aber es gibt keine Commit-Anweisung, die das für Ihre Datenbank beibehalten würde. Daher kann die Laravel-Validierungsregel "exists" diese nicht finden (diese Regel veranlasst eine Datenbankanforderung, eine bestimmte user_id zu finden).

Also in Ihrem Fall müssen die Benutzer vor dem Testen existieren. Ich würde stattdessen empfehlen, Migrationen zu verwenden. Resetting Database after each test

Erstellen Sie Ihre Tabellen mit Datenbankmigrationen und Seeds, und rollen Sie sie nach Abschluss der Tests zurück.

+0

Ich hatte gehofft, die Datenbank vor jedem Test migrieren zu können. Es sieht so aus, als hätte dies eine hohe Leistungseinbuße im Vergleich zur Ausführung innerhalb einer Transaktion. Was ich nicht wirklich verstehe, ist, wie Laravels Validator die von mir erstellten Benutzer nicht sehen kann. Sind Laravel und Codeception zwei verschiedene Datenbankverbindungen? –

0

Zitat:

$I->sendPOST('users/' . $users[0]->id . '/friendships', [ 
    'user_id' => $users[1]->id 
]); 

Warum Sie $users[0]->id im Anforderungs-URL senden und dann 'user_id' => $users[1]->id in den Parametern?

Könnte das Ihr Problem sein? Könnte dies der Grund sein, warum Sie die Validierung nicht bestehen?

+0

Das ist nicht das Problem. Dieser Endpunkt akzeptiert die Benutzer-ID eines * anderen * Benutzers, mit dem Sie Freunde haben möchten. –