События модели Laravel 4 не работают с PHPUnit

Я создаю проверку модели в Laravel 4 с помощью creating Модель Событий :

class User extends Eloquent {

    public function isValid()
    {
        return Validator::make($this->toArray(), array('name' => 'required'))->passes();
    }

    public static function boot()
    {
        parent::boot();

        static::creating(function($user)
        {
            echo "Hello";
            if (!$user->isValid()) return false;
        });
    }
}

он работает хорошо, но у меня проблемы с PHPUnit. Два следующих теста точно такие же, но juste первый проход:

class UserTest extends TestCase {

    public function testSaveUserWithoutName()
    {
        $count = User::all()->count();

        $user = new User;
        $saving = $user->save();

        assertFalse($saving);                       // pass
        assertEquals($count, User::all()->count()); // pass
    }

    public function testSaveUserWithoutNameBis()
    {
        $count = User::all()->count();

        $user = new User;
        $saving = $user->save();

        assertFalse($saving);                       // fail
        assertEquals($count, User::all()->count()); // fail, the user is created
    }
}

если я пытаюсь создать пользователя дважды в одном тесте, он работает, но это похоже на то, что событие привязки присутствует только в первом тесте моего тестового класса. The echo "Hello"; печатается только один раз, во время первого испытания исполнение.

я упрощаю случай для моего вопроса, но вы можете увидеть проблему: я не могу проверить несколько правил проверки в разных модульных тестах. Я пробую почти все с часов, но я близок к тому, чтобы выпрыгнуть из окон сейчас ! Есть идеи ?

2 ответов


проблема хорошо документирована в Github. См. комментарии выше, которые объясняют это далее.

Я изменил одно из "решений" в Github для автоматического сброса всех событий модели во время тестов. Добавьте в свой TestCase следующее.PHP-файл.

приложение / тесты / TestCase.в PHP

public function setUp()
{
    parent::setUp();
    $this->resetEvents();
}


private function resetEvents()
{
    // Get all models in the Model directory
    $pathToModels = '/app/models';   // <- Change this to your model directory
    $files = File::files($pathToModels);

    // Remove the directory name and the .php from the filename
    $files = str_replace($pathToModels.'/', '', $files);
    $files = str_replace('.php', '', $files);

    // Remove "BaseModel" as we dont want to boot that moodel
    if(($key = array_search('BaseModel', $files)) !== false) {
        unset($files[$key]);
    }

    // Reset each model event listeners.
    foreach ($files as $model) {

        // Flush any existing listeners.
        call_user_func(array($model, 'flushEventListeners'));

        // Reregister them.
        call_user_func(array($model, 'boot'));
    }
}

У меня есть мои модели в подкаталогах, поэтому я немного отредактировал @ TheShiftExchange code

//Get all models in the Model directory
$pathToModels = '/path/to/app/models';
$files = File::allFiles($pathToModels);

foreach ($files as $file) {
    $fileName = $file->getFileName();
    if (!ends_with($fileName, 'Search.php') && !starts_with($fileName, 'Base')) {
        $model = str_replace('.php', '', $fileName);
        // Flush any existing listeners.
        call_user_func(array($model, 'flushEventListeners'));
        // Re-register them.
        call_user_func(array($model, 'boot'));
    }
}