Php Laravel模型事件保存未启动

Php Laravel模型事件保存未启动,php,unit-testing,laravel,eloquent,Php,Unit Testing,Laravel,Eloquent,我正在尝试模拟Ardent软件包正在做的事情。即在保存之前验证模型 我创建了这个BaseModel(根据Laravel Testing decoded书)。并添加了以下代码: class BaseModel extends Eloquent { protected static $rules = []; public $errors = []; public function validate(){ $v = Validator::make($this-

我正在尝试模拟
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()
返回true

class PostTest extends TestCase {

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

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

保存事件对我来说很好。验证失败,因此
$post->save()
返回false。您的测试通过,因为您希望
$post->save()
为false(
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());
}

查看以下讨论:

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

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()测试方法中。

请注意,这是不鼓励的,因此答案应该是搜索解决方案的终点(而不是另一个参考的中途停留,它往往会随着时间的推移而过时)。请考虑在这里添加一个独立的概要,把链接作为参考。谢谢,我想不出为什么它不起作用: