Laravel 4模型事件不';我不能和PHPUnit一起工作
我在Laravel 4中通过Laravel 4模型事件不';我不能和PHPUnit一起工作,phpunit,laravel,laravel-4,Phpunit,Laravel,Laravel 4,我在Laravel 4中通过创建模型事件构建模型端验证: class User extends Eloquent { public function isValid() { return Validator::make($this->toArray(), array('name' => 'required'))->passes(); } public static function boot() { p
创建
模型事件构建模型端验证:
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有问题。以下两项测试完全相同,但只是第一次通过:
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
}
}
如果我在同一个测试中尝试创建一个用户两次,它会起作用,但就像绑定事件只出现在测试类的第一个测试中一样。回显“Hello”代码>仅在第一次测试执行期间打印一次
我简化了我的问题,但您可以看到问题:我无法在不同的单元测试中测试多个验证规则。从几个小时开始,我几乎尝试了所有的事情,但现在我几乎要跳出窗户了!有什么想法吗?这个问题在Github中有很好的记录。请参阅上面的注释,进一步解释
我修改了Github中的一个“解决方案”,以便在测试期间自动重置所有模型事件。将以下内容添加到TestCase.php文件中
app/tests/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'));
}
}
公共功能设置()
{
父::设置();
$this->resetEvents();
}
私有函数resetEvents()
{
//获取模型目录中的所有模型
$pathToModels='/app/models';//我的模型在子目录中,所以我编辑了@TheShiftExchange代码
//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'));
}
}
阅读谢谢。最后,模型事件不容易测试。我用这个技巧解决了我的问题:在我的setUp()
方法中调用User::boot()
。我更喜欢使用User::observe(new UserObserver)
,这样你就可以自己测试UserObserver
。@AlexandreButynski我也这么做了,最终它是一个简洁的、全面的解决方案,似乎没有合适的解决方案。希望这是可行的,这要感谢雄辩模型上的\uu callStatic
方法(Model::boot
受protected
),它省去了我们在模型上定义公共方法以使其可测试的麻烦。感谢您的提示!它以比我的基本技巧更通用的方式解决了我的问题(只需为每个模型添加一行,如User::boot()
)但有两个原因让我感到困惑:它在我的TestCase类中添加了一堆奇怪的代码,并在每次测试之前解析文件(这可能会导致性能问题)…需要先测试模型是否扩展了模型,但有时它们可能没有flushEventListeners方法。