2017-02-21 11 views
0

Ich habe derzeit einige Probleme beim Testen einer Funktion in Laravel. Diese Funktion ist eine einfache Benutzerfunktion zum Speichern.Laravel Unit-Test Eloquent Insertion

Die derzeitige Struktur eines Benutzer

class User extends Authenticatable 

beinhaltet Dann habe ich eine Usercontroller

class UserController extends Controller 
{ 
protected $user; 

public function __construct(User $user) 
{ 
    $this->user = $user; 
    $this->middleware('admins'); 
} 

Die Save-Funktion auf der Usercontroller Klasse definiert ist, diese Klasse ordnet nur die Anforderung Variablen und verwendet Eloquent speichern Funktion zum Speichern in der Datenbank.

Die Funktion Unterschrift ist die folgende:

public function storeUser($request) 
{ 

    $this->user->name  = $request->name; 
    $this->user->email  = $request->email; 
    $this->user->country_id = $request->country_id; 

    return $this->user->save(); 
} 

Das NewAccountRequest Objekt aus Antrag erstreckt und die Prüfregeln für die Anforderung.

class NewAccountRequest extends Request 
{ 
public function authorize() 
{ 
    return true; 
} 

public function rules() 
{ 
    return [ 
     'name' => 'required|max:255', 
     'email' => 'required|email|max:255|unique:user', 
     'password' => 'required|min:6|max:60', 
    ]; 
} 

} 

Mein Problem ist, wie kann ich diese StoreUser-Funktion Einheit testen.

ich den aktuellen Test haben:

public function testSaveUserWithEmptyRequest() 
{ 

    $user = $this->createMock(User::class); 
    $controller = new UserController($user); 

    $request = $this->createMock(NewAccountRequest::class); 
    $store = $controller->storeUser($request); 

    $this->assertFalse($store); 
} 

ich beide Benutzer und NewAccountRequest bin verspotten, ist das Problem, dass die Behauptung falsch sein sollte, von der Eloquent speichern. Stattdessen bekomme ich Null. Irgendeine Idee, wie ich die Funktion richtig testen kann?

+0

Was innen 'saveUser' Funktion ist, werden Sie eine return-Anweisung fehlt ? –

+0

@ShadyAtef Die Frage wurde mit dem StoreUser-Code und einer Korrektur des Call-Namens aktualisiert. –

+0

Ich habe es, Sie verspotten die 'User :: Klasse' .. In PHPUnit' createMock' ersetzt alle Funktionen eines Objekts mit Dummy, die nichts tun und null zurückgeben. In der Tat, um Datenbank-Betrieb in Laravel zu testen, müssen Sie eine der beiden Eigenschaften 'DatabaseMigrations' oder' DatabaseTransactions' –

Antwort

0
<?php 
namespace Tests\Unit; 

use Tests\TestCase; 
use Illuminate\Foundation\Testing\DatabaseMigrations; 
use Illuminate\Foundation\Testing\DatabaseTransactions; 

class ExampleTest extends TestCase 
{ 
    use DatabaseTransactions; // Laravel will automatically roll back changes that happens in every test 


    public function testSaveUserWithEmptyRequest() 
    { 

     $user = new User(); 
     $controller = new UserController($user); 

     $request = $this->createMock(NewAccountRequest::class); 
     $store = $controller->storeUser($request); 

     $this->assertFalse($store); 
    } 

} 

Das ist genau das, was Sie zu tun versuchen, aber leider wird dies aufgrund Datenbank Ausnahmen scheitern ... eine Anfrage Mocking oder auch manuell Crafting wird es nicht tun, um Ihnen die Dateneingabevalidierung .. und in Beispiel password Feld nicht NULL sein kann und wird PDOException: SQLSTATE[HY000]: General error: 1364 Field 'password' doesn't have a default value


Der empfohlene Weg führt Funktionen zu testen, auf Anfrage abhängig ist http Test Helfer von Laravel zu nutzen wie $response = $this->post('/user', ['name' => 'Sally']);


Ein viel besserer Ansatz ist das Repository Design-Muster zu verwenden .. Dies bedeutet einfach Ihre Datenbank-Funktionen in separate Klassen zusammenstellen und es von Controllern nennen ..

+0

Wird versuchen zu testen mit den Routen, geben Sie Feedback, wenn ich es tue. Vielen Dank! –

+0

Oh etwas anderes habe ich vergessen zu sagen, Sie versuchen '$ this-> expectException (\ PDOException :: class);' am Anfang des Tests, um die geworfene Ausnahme zu fangen .. –