使用Laravel测试模型验证时遇到问题

时间:2014-04-19 17:23:19

标签: unit-testing testing laravel laravel-4 tdd

我刚刚开始使用TDD,我正在尝试在模型中测试验证。目前,我的所有测试都通过了,但我相信他们不应该。 testBodyIsRequiredToValidate()应该失败,因为我还没有将它添加到rules数组中。当我从rules数组中删除所需的标题时,我的所有测试都按预期失败。但是,添加标题会导致所有标题都通过。

我的测试:

class PostTest extends TestCase {

    public function testTitleIsRequiredToValidate()
    {
        $post = new Post;
        $post->body = 'foobar';

        $this->assertFalse($post->validate(compact('post')));
    }

    public function testBodyIsRequiredToValidate()
    {
        $post = new Post;
        $post->title = 'foobar';

        $this->assertFalse($post->validate(compact('post')));
    }
}

我的模特:

class Post extends Eloquent {

    public function validate($input)
    {
        $rules = array(
            'title' => 'required'
        );

        $v = Validator::make($input, $rules);

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

}

1 个答案:

答案 0 :(得分:1)

这是因为您的验证错误。您将模型本身传递给验证器,但是您应该传递一个关联数组。

  • 当您从规则中删除title时,您会传递一个空规则,因此验证将始终为真,这就是为什么所有测试都失败。
  • 当您在规则中添加title时,验证将始终为false,因此所有测试都会通过,因为验证程序的第一个参数没有名为title的数组元素。

解决此问题的一种方法是将验证行更改为:

$v = Validator::make(array('title' => $input['post']->title), $rules);

您可以从$post数组中获取$input,因为compact()会将其放入带有变量名称键的数组中。然后,您可以访问对象的title属性,并将其设置为title键的值,以便验证程序能够找到并验证它。

我必须提到你的验证技术对我有点不好。您将数组中的对象传递给同一对象的函数。你为什么不在函数中得到对象?

我会像这样编写验证器函数:

public function validate() {
    $rules = array(
        'title' => 'required'
    );

    $v = Validator::make($this->toArray(), $rules);

    return $v->passes();
}

所以我可以在测试中调用这样的函数:

$this->assertFalse($post->validate());