【问题标题】:Laravel model event saving is not firingLaravel 模型事件保存未触发
【发布时间】:2013-09-11 22:51:00
【问题描述】:

我正在尝试模拟 Ardent 包在做什么。这是在保存之前验证模型。

我创建了这本书BaseModel(根据Laravel Testing decoded 书)。并添加了这段代码:

class BaseModel extends Eloquent {
    protected static $rules = [];
    public $errors = [];

    public function validate(){
        $v = Validator::make($this->attributes, static::$rules);

        if($v->passes()) {
            return true;
        }

        $this->errors = $v->messages();

        return false;
    }

    public static function boot(){
        parent::boot();
        static::saving(function($model){
            if($model->validate() === true){
                foreach ($model->attributes as $key => $value) {
                    if(preg_match("/[a-zA-Z]+_confirmation/", $key)){
                        array_splice($model->attributes, array_search($key, array_keys($model->attributes)), 1);
                    }
                }
                echo "test"; //This is for debugging if this event is fired or not
                return true;
            } else {
                return false;
            }
        });
    }
}

现在,这是我的Post 模型:

class Post extends BaseModel {
    public static $rules = array(
            'body' => 'required',
            'user_id' => 'required',
        );

}

在这个测试中,我预计它会失败。相反,它通过了! , $post->save() 返回真!

class PostTest extends TestCase {

    public function testSavingPost(){
        $post = new Post();
        $this->assertFalse($post->save());
    }
}

当我尝试在 saving 事件中抛出 echo 语句时。它没有出现,所以我知道我定义的saving 事件没有被调用。我不知道为什么。

【问题讨论】:

    标签: php unit-testing laravel eloquent


    【解决方案1】:

    查看此讨论:https://github.com/laravel/framework/issues/1181

    您可能需要在测试中重新注册您的事件。

    class PostTest extends TestCase {
    
        public function setUp()
        {
            parent::setUp();
    
            // add this to remove all event listeners
            Post::flushEventListeners();
            // reboot the static to reattach listeners
            Post::boot();
        }
    
        public function testSavingPost(){
            $post = new Post();
            $this->assertFalse($post->save());
        }
    }
    

    或者,更好的是,您应该将事件注册功能从引导函数中提取到公共静态方法中:

      class Post extends Model {
    
           protected static boot()
           {
               parent::boot();
               static::registerEventListeners();
           }
    
           protected static registerEventListeners()
           {
               static::saving(...);
               static::creating(...);
               ...etc.
           }
    
      }
    

    然后调用 Post::flushEventListeners(); Post::registerEventListeners();在 setUp() 测试方法中。

    【讨论】:

    • 请注意 link-only answers 是不鼓励的,所以答案应该是寻找解决方案的终点(而不是另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。
    • 谢谢,我不明白为什么这不起作用:-)
    【解决方案2】:

    保存事件对我来说看起来不错。验证失败,所以 $post->save() 返回 false。您的测试通过了,因为您期望 $post->save() 为假 (assertFalse),在这种情况下是正确的。 请尝试这些测试。

    public function testSavingInvalidPost() {
        $post = new Post();
        $this->assertFalse($post->save());
    }
    
    public function testSavingValidPost() {
        $post = new Post();
        $post->body = 'Content';
        $post->user_id = 1;
        $this->assertTrue($post->save());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-08
      • 2014-08-15
      • 2021-09-19
      • 1970-01-01
      • 2022-12-04
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多