События модели 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'));
}
}