2015-03-19 5 views
5

Ich schreibe Tests für ein Modell, das ein Ereignis auslöst, wenn eine seiner Eigenschaften geändert wird. Leider kann ich den besten Weg, dies zu testen, nicht herausfinden. Der Modellcode ist:Wie kann ich Laravel-Ereignisse richtig testen?

class Foo extends Eloquent { 
    public function setNameAttribute($value) { 
     $this->attributes['name'] = $value; 
     if($this->exists && ($this->original['name'] != $value)) { 
      Event::fire('foo.NameChange', array($this)); 
     } 
    } 
} 

Mein erster Test für das Ereignis Feuer:

$bar = Foo::first(); 
Event::shouldReceive('fire')->once()->with('foo.NameChange', array($bar)); 
$bar->name = 'test'; 

Das Problem ist, nach wie vor die oben genannten Prüfungen bestehen, wenn:

  • kein Ereignis bei allen
  • aufgetreten
  • Ich ändere den Namen des Modells ein zweites Mal (das sollte das Ereignis ein zweites Mal auslösen, oder?)

Wie kann ich meine Tests nur bestehen lassen, wenn eine foo.NameChange Ereignis aufgetreten ist? Alle anderen Senario's sollten meinen Test nicht bestehen.

+0

Ihr Test sollte fehlschlagen, wenn überhaupt kein "Ereignis" aufgetreten ist - wie Sie es verspottet haben und sagten, es sollte "einmal" ausgelöst werden? – Laurence

+0

Haben Sie 'Spott :: close()'? Gerufen, sehen Sie auch meine Erklärung auf einer [alten SO-Frage] (http://stackoverflow.com/questions/16035549/servietten-sollen-empfangen-jetzt-kommen-) Arbeit/16308814 # 16308814) –

+0

Vielen Dank @BramGerritsen! Schließen Sie den Test mit einer 'Spotty :: close()' Anweisung hat es behoben! Könnten Sie Ihren Kommentar zu einer Antwort konvertieren? Ich frage mich auch, warum dies in der offiziellen Dokumentation von [Laravel] (http://laravel.com/docs/4.2/testing#mocking-facades) nicht erwähnt wird. – nstapelbroek

Antwort

2

Sie müssen Mockery::close() in Ihrer tearDown() Methode aufrufen. Siehe die Mockery docs PHPUnit-Integration.