Frage

I'm just starting out with TDD and I'm trying to test validation in a model. Currently, all my tests pass, but I believe that they shouldn't. The testBodyIsRequiredToValidate() should fail since I have not added it to the rules array. When I remove the title required from the rules array, all my tests fail as expected. However, adding title required causes them all to pass.

My Tests:

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')));
    }
}

My Model:

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

}
War es hilfreich?

Lösung

This happens because your validation is wrong. You pass the model itself to the validator but you should pass an associative array.

  • When you delete title from the rules you pass an empty rule, so the validation will be always true, thats why all your test fail.
  • When you add title to your rules, the validations will be always false hence all your tests pass, because the validator's first parameter doesn't have an array element called title.

One way to correct this is to change your validation line to this:

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

Here you get the $post from your $input array, because compact() will put it to an array with the key of the variable name. Then you access the title property of the object and make this to the value of the title key so the validator will be able to find and validate it.

I have to mention that your validation technique is kinda bad for me. You pass the object in an array to a function of the same object. Why don't you get the object in the function?

I would write the validator function like this:

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

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

    return $v->passes();
}

So I could call the function like this in the tests:

$this->assertFalse($post->validate());
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top