2016-01-29 14 views
11

Quindi, ho una pagina con un pulsante su di esso con il valore "Crea". Quando faccio clic sul pulsante Crea, senza riempire nessuno dei campi, esso convalida il modulo e visualizza i messaggi di errore sulla stessa pagina. Quando lo faccio nel browser, funziona bene, ma quando lo faccio con phpunit, ha risultati inaspettati e non so perché.Il test della phpunit di Laravel non funziona. Andando a una pagina inaspettata. Succede solo nel test

Ecco il mio test di integrazione:

public function testCreateValidation()          
{ 
    $this->visit(route('patients.indexes.create', $this->patient->id));  
    $this->press('Create');             
    $this->seePageIs(route('patients.indexes.create', $this->patient->id));    
} 

E questo è il risultato:

There was 1 failure: 
1) Tests\Integration\IndexControllerTest::testCreateValidation 
Did not land on expected page [http://localhost/patients/69/indexes/create]. 

Failed asserting that two strings are equal. 
--- Expected 
+++ Actual 
@@ @@ 
-'http://localhost/patients/69/indexes/create' 
+'http://localhost/patients' 

/vagrant/vendor/laravel/framework/src/Illuminate/Foundation/Testing/InteractsWithPages.php:141 
/vagrant/tests/Integration/IndexControllerTest.php:51 

Non capisco il motivo per cui viene reindirizzato alla pagina patients.

Ecco la create metodo di laravel che è in fase di test:

public function create($id)               
{                     
    $index = $this->indexes->newInstance();           
    $patient = $this->patients->findOrFail($id);          

    return view('patient.index.create', ['index' => $index, 'patient' => $patient]); 
} 

E qui è la sezione dedicata del panorama create:

<?= Form::open(['route' => array('patients.indexes.store', $patient->id), 'class' => 'form-horizontal']) ?> 
    @include('patient.index._form') 
    <?= Form::submit('Create', ['class' => 'btn btn-primary']) ?> 
<?= Form::close() ?> 

E infine il metodo store che è stato inviato a:

public function store(IndexRequest $request, $id)  
{              
    $index = $this->indexes->newInstance();    
    $index->fill($request->all());      
    $index->patient_id = $id;       
    $index->save();          

    $patient = $index->patient;       

    return redirect()->route('patients.edit', $patient); 
} 

Sono anche utilizzando un FormRequest per convalidare l'input:

public function rules()     
{           
    return [        
     'index_title' => 'required',  
     'index_description' => 'required', 
    ];          
} 

Quindi, in sostanza, dal momento che sta venendo a mancare la convalida nel IndexRequest, il IndexRequest dovrebbe calci di nuovo ai patients.indexes.create vista e visualizzazione errori. Ma per qualche motivo viene dato un calcio alla pagina dei pazienti (questo accade SOLO nel test, se provo facendo clic manualmente sul pulsante Crea nel browser, funziona come previsto)

Ho riscontrato questo problema prima ma non sono mai stato in grado di risolverlo. Qualche idea?

+0

Quale versione di laravel sono in esecuzione? – BrokenBinary

risposta

4

Sembra che tu stia avendo problemi CSRF. Quando si naviga nel modulo nel browser, Laravel memorizza un special token nei cookie del browser e nelle intestazioni della richiesta. Quindi, quando invii il modulo, cerca quel token per assicurarti di essere quello che invia il modulo.

Quando si esegue il test con PHPUnit, il token non viene inviato, quindi è necessario inviarlo manualmente oppure è necessario escludere i test dal middleware che controlla il token. Escludere i test è il metodo più semplice.

In Laravel 5.0 l'ho fatto sovrascrivendo il metodo handle() nel middleware VerifyCsrfToken.

class VerifyCsrfToken extends BaseVerifier { 
    // Override the handle() method in the BaseVerifier class 
    public function handle($request, Closure $next) { 
     // When the App environment is 'testing', skip CSRF validation. 
     if (app()->environment() === 'testing') { 
      return $next($request); 
     } 

     return parent::handle($request, $next); 
    } 
} 

Per impostazione predefinita, PHPUnit tira le variabili di ambiente dal file phpunit.xml nel tuo sito principale laravel. La variabile APP_ENV è quella che controlla il nome dell'ambiente dell'applicazione e, per impostazione predefinita, "verifica". Se il tuo è diverso, devi quindi modificare il codice che ho fornito per abbinarlo.

1

Se il middleware è in realtà il problema è possibile escludere che dalle prove che utilizzano il tratto WithoutMiddleware:

class IndexControllerTest extends TestCase 
{ 
    use Illuminate\Foundation\Testing\WithoutMiddleware; 
    ...