Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Rodrigo Balest's avatar

How to test custom validation rules in Laravel 5?

Hi!

I also posted this question at StackOverflow.

I created a custom validation rule in Laravel, extending it in the register() method of a service provider, and I'd like to test it, but don't know how.

I took a look at Laravel framework's validation tests, but I couldn't understand the purpose of the getTranslator() and getRealTranslator() methods.

Could someone give me a hint on how to test Laravel's custom validation rules?

That's what I did:

Created a ValidatorServiceProvider as follows:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ValidatorServiceProvider extends ServiceProvider {

    /**
    * Bootstrap the application services.
    *
    * @return void
    */
    public function boot()
    {
        $this->app['validator']->extend('greater_than', function($attr, $val, $params)
        {
            return false;
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
    }
}

Also added it to the providers array and issued composer dump-autoload -o.

Added the following to tests\CustomValidationRulesTest.php:

<?php

use Mockery as m;
use Illuminate\Validation\Validator;

class CustomValidationRulesTest extends TestCase {
    
    public function tearDown()
    {
        m::close();
    }

    public function testValidateGreaterThan()
    {
        $trans = $this->getTranslator();
        
        $rules = [
            'field2' => 'greater_than:field1'
        ];
        
        $data = [
            'field1' => 1,
            'field2' => 2
        ];
        
        $v = new Validator($trans, $data, $rules);
        $this->assertTrue($v->passes());
    }
    
    protected function getTranslator()
    {
        return m::mock('Symfony\Component\Translation\TranslatorInterface');
    }
    
    protected function getRealTranslator()
    {
        $trans = new Symfony\Component\Translation\Translator('en', new Symfony\Component\Translation\MessageSelector);
        $trans->addLoader('array', new Symfony\Component\Translation\Loader\ArrayLoader);
        return $trans;
    }

}

Running PHPUnit gives me the following:

PHPUnit 4.6.6 by Sebastian Bergmann and contributors.

Configuration read from /home/ubuntu/workspace/phpunit.xml

E.

Time: 248 ms, Memory: 14.75Mb

There was 1 error:

1) CustomValidationRulesTest::testValidateGreaterThan
BadMethodCallException: Method [validateGreaterThan] does not exist.

/home/ubuntu/workspace/vendor/laravel/framework/src/Illuminate/Validation/Validator.php:2615
/home/ubuntu/workspace/vendor/laravel/framework/src/Illuminate/Validation/Validator.php:372
/home/ubuntu/workspace/vendor/laravel/framework/src/Illuminate/Validation/Validator.php:372
/home/ubuntu/workspace/vendor/laravel/framework/src/Illuminate/Validation/Validator.php:325
/home/ubuntu/workspace/tests/CustomValidationRulesTest.php:27

What I'm doing wrong?

Thanks!

0 likes
3 replies
Sannim1's avatar

try refreshing the application. add $this->refreshAppliction() to your test class setUp() method

public function setUp() { parent::setUp; $this->refreshApplication(); }
//then call your test
public function testValidateGreaterThan() { }

1 like
adamwathan's avatar

Since you are extending the validator that's in the IOC, you need to test the one that's in the IOC. I'm guessing that newing up your own Validator isn't giving you one that has the extension registered.

Since the test depends on the service provider registering the extension with the validation factory that's in the container, I wouldn't bother with trying to mock anything in that test.

Try something like this:

<?php

class CustomValidationRulesTest extends TestCase
{
    public function testValidateGreaterThan()
    {
        $rules = [
            'field2' => 'greater_than:field1'
        ];
        
        $data = [
            'field1' => 1,
            'field2' => 2
        ];
        
        $v = $this->app['validator']->make($data, $rules);
        $this->assertTrue($v->passes());
    }
}
25 likes

Please or to participate in this conversation.