Laravel 4 Model Events不适用于PHPUnit

我使用creating模型事件在Laravel 4中构建模型端验证:

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
    }
}

如果我尝试在同一个测试中创建两次用户,它会起作用,但这就好像绑定事件仅出现在我的测试类的第一个测试中。 echo "Hello"; 仅在第一次测试执行期间打印一次。

我简化了我的问题,但您可以看到问题:我不能在不同的单元测试中测试多个验证规则。 几小时后我几乎尝试了所有的事情,但我快要跳出窗户了! 任何想法 ?


这个问题在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代码

//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'));
    }
}
链接地址: http://www.djcxy.com/p/14587.html

上一篇: Laravel 4 Model Events don't work with PHPUnit

下一篇: Active Record or Data Mapper pattern for Angularjs?