Summer Sale! All accounts are 50% off this week.

eojeel's avatar
Level 11

Testing ValidationRule directly using pest.

Hi All,

If anyone has any pointers on my below issue it would be greatly appreciated.

I have been playing around with pest and attempted to write a test for this IsValidEmailAddress rule i have been playing with.

Custom validation rule https://laravel.com/docs/10.x/validation#custom-validation-rules but regardless of what avenue i try and go down to validate the test i keep hitting a roadblock, reading the facade documentation https://laravel.com/api/8.x/Illuminate/Contracts/Validation/Validator.html validated() should return the attributes that were validated but its always an empty array.

Validation Rule

class IsValidEmailAddress implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if(! is_string($value)) {
            $fail('The value must be a string!');
        }

        if(!preg_match_all('/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/', $value))
        {
            $fail('The value must be a valid email address!');
        }
    }
}

Tests

it('can validate an email', function () {
    $validator = Validator::make(['email' => '[email protected]'], [new IsValidEmailAddress()]);

    expect($validator->validated())->toBe(['email' => '[email protected]']);

});

Output

   FAILED  Tests\Feature\emailTest > it can validate an email                                                                               
  Failed asserting that two arrays are identical.
  -Array &0 (
  -    'email' => '[email protected]'
  -)
  +Array &0 ()
0 likes
3 replies
LaryAI's avatar
Level 58

The issue with the test is that the email address being passed to the validator is not a valid email address. Therefore, the validation rule is correctly failing and the validated method is returning an empty array. To fix the test, a valid email address should be passed to the validator. For example:

it('can validate an email', function () {
    $validator = Validator::make(['email' => '[email protected]'], [new IsValidEmailAddress()]);

    expect($validator->validated())->toBe(['email' => '[email protected]']);
});
eojeel's avatar
eojeel
OP
Best Answer
Level 11

Fixed it.

Sill me forgot to pass the attribute name when defining the validation rules.

it('can validate an email', function () {
    $validator = Validator::make(['email' => '[email protected]'], ['email' => new IsValidEmailAddress()]);

    expect($validator->validated())->toBe(['email' => '[email protected]']);
});

Please or to participate in this conversation.