Scenario
Our form is expecting user input from a specific field is typed in all capital letters so we have a custom validation rule to check if the input is uppercase. Writing tests for a custom Laravel validation rule is simple once you get started.
Example Custom Rule
The uppercase rule is the example from the Laravel docs. Here’s what the class looks like.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Writing Tests
When we’re writing tests we need to think of the use cases or scenarios that may occur. In our case we have a few different types of strings that should be invalid and only one case when it will be valid.
Take the word flowers for example. The only valid way to pass our new rule would be FLOWERS. These are the different scenarios or tests cases we may want to test so that we know our validation rule validates every type of use case.
- FLOWERS // Valid
- Flowers // Invalid
- flowers // Invalid
Now we know which use cases should pas and faile lets write the tests. Our test class would look something like this.
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
class ExampleTest extends TestCase
{
public function testAllUppercasePasses()
{
$rule = new App\Rule\Uppercase()
$this->assertTrue($rule->passes('attribute', 'FLOWERS');
}
public function testOneUppercaseLetterIsInvalid()
{
$rule = new App\Rule\Uppercase()
$this->assertTrue($rule->passes('attribute', 'Flowers');
}
public function testAllLowercaseIsInvalid()
{
$rule = new App\Rule\Uppercase()
$this->assertTrue($rule->passes('attribute', 'flowers');
}
}
Each test is asserting a different use case. Separate tests are easier to read and when something fails it’s easier to determine what failed.
Now that we have tests for our rule we know when using this rule as a part of validation that it will work. If for some reason it doesn’t work write a test for the scenario it didn’t work for. Watch the test fail. Fix the scenario and watch the test pass. Rinse and repeat.
Happy testing!