Created
July 24, 2019 08:35
-
-
Save tuanpht/37394e0df10d48d08d0d406c9a7dd477 to your computer and use it in GitHub Desktop.
Laravel Form Request Testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Foundation\Http\FormRequest; | |
use Illuminate\Validation\Rules\Unique; | |
class RegisterRequest extends FormRequest | |
{ | |
const NAME_MAX_LENGTH = 255; | |
const EMAIL_MAX_LENGTH = 255; | |
const PASSWORD_MIN_LENGTH = 8; | |
/** | |
* @return array | |
*/ | |
public function rules() | |
{ | |
return [ | |
'name' => ['required', 'string', 'max:' . self::NAME_MAX_LENGTH], | |
'email' => ['required', 'string', 'email', 'max:' . self::EMAIL_MAX_LENGTH, new Unique('users', 'email')], | |
'password' => ['required', 'string', 'min:' . self::PASSWORD_MIN_LENGTH, 'confirmed'], | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Tests\TestCase; | |
use App\Http\Requests\Web\RegisterRequest; | |
use Illuminate\Support\Facades\Validator; | |
use Illuminate\Validation\PresenceVerifierInterface; | |
class RegisterRequestTest extends TestCase | |
{ | |
public function test_it_contains_valid_rules() | |
{ | |
$request = new RegisterRequest; | |
$this->assertEquals([ | |
'name' => ['required', 'string', 'max:' . RegisterRequest::NAME_MAX_LENGTH], | |
'email' => ['required', 'string', 'email', 'max:' . RegisterRequest::EMAIL_MAX_LENGTH, new Unique('users', 'email')], | |
'password' => ['required', 'string', 'min:' . RegisterRequest::PASSWORD_MIN_LENGTH, 'confirmed'], | |
], $request->rules()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Tests\Unit\Http\Requests\Web; | |
use Tests\TestCase; | |
use App\Http\Requests\Web\RegisterRequest; | |
use Illuminate\Support\Facades\Validator; | |
use Mockery; | |
use Illuminate\Validation\PresenceVerifierInterface; | |
class RegisterRequestTest extends TestCase | |
{ | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidateNameSuccess | |
*/ | |
public function testValidateNameSuccess($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'name'); | |
$validator = Validator::make($data, $rules); | |
$passed = $validator->passes(); | |
// Can be debug with | |
// dd($validator->failed()); | |
$this->assertTrue($passed); | |
} | |
public function provideDataValidateNameSuccess() | |
{ | |
return [ | |
[['name' => 'Valid name']], | |
[['name' => str_repeat('a', RegisterRequest::NAME_MAX_LENGTH)]], | |
]; | |
} | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidateNameFailed | |
*/ | |
public function testValidateNameFailedWhenMissingInput($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'name'); | |
$validator = Validator::make($data, $rules); | |
$passed = $validator->passes(); | |
$this->assertFalse($passed); | |
} | |
public function provideDataValidateNameFailed() | |
{ | |
return [ | |
[[]], | |
[['name' => ' ']], | |
[['name' => '']], | |
]; | |
} | |
public function testValidateNameFailedWhenExceedingMaxlength() | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'name'); | |
$validator = Validator::make([ | |
'name' => str_repeat('a', RegisterRequest::NAME_MAX_LENGTH + 1), | |
], $rules); | |
$passed = $validator->passes(); | |
$this->assertFalse($passed); | |
} | |
/** | |
* Fake database connection when using some db rules, e.g. unique, exists... | |
*/ | |
private function fakeDatabaseRuleVerifier($validator) | |
{ | |
$presenceVerifier = Mockery::mock(PresenceVerifierInterface::class); | |
/* | |
* Interface PresenceVerifierInterface does not have method setConnection, | |
* but validator call that method somewhere, so we need to mock that method also. | |
* | |
* It's a hack, not good | |
* https://github.com/laravel/framework/issues/12250 | |
*/ | |
$presenceVerifier->shouldReceive('setConnection'); | |
$validator->setPresenceVerifier($presenceVerifier); | |
return $presenceVerifier; | |
} | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidateEmailSuccess | |
*/ | |
public function testValidateEmailSuccess($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'email'); | |
$validator = Validator::make($data, $rules); | |
$presenceVerifier = $this->fakeDatabaseRuleVerifier($validator); | |
$presenceVerifier->shouldReceive('getCount')->andReturn(0); | |
$passed = $validator->passes(); | |
$this->assertTrue($passed); | |
} | |
public function provideDataValidateEmailSuccess() | |
{ | |
return [ | |
[['email' => 'validemail@example.com']], | |
]; | |
} | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidateEmailFailedWhenEmailInvalid | |
*/ | |
public function testValidateEmailFailedWhenEmailInvalid($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'email'); | |
$validator = Validator::make($data, $rules); | |
$presenceVerifier = $this->fakeDatabaseRuleVerifier($validator); | |
// We are testing email format | |
// so we make getCount return 0, meaning email had not existed in db | |
$presenceVerifier->shouldReceive('getCount')->andReturn(0); | |
$passed = $validator->passes(); | |
$this->assertFalse($passed); | |
} | |
public function provideDataValidateEmailFailedWhenEmailInvalid() | |
{ | |
return [ | |
[[]], | |
[['email' => '']], | |
[['email' => ' ']], | |
[['email' => 'missingdomain']], | |
[['email' => '@missinguser.com']], | |
[['email' => 'invalidchar &*@example.com']], | |
[['email' => 'exceedlength' . str_repeat('a', RegisterRequest::EMAIL_MAX_LENGTH + 1) . '@example.com']], | |
]; | |
} | |
public function testValidateEmailFailedWhenEmailExisted() | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'email'); | |
$validator = Validator::make([ | |
'email' => 'existedemail@example.com', | |
], $rules); | |
$presenceVerifier = $this->fakeDatabaseRuleVerifier($validator); | |
$presenceVerifier->shouldReceive('getCount')->andReturn(1); | |
$passed = $validator->passes(); | |
$this->assertFalse($passed); | |
} | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidatePasswordFailedWhenInputInvalid | |
*/ | |
public function testValidatePasswordFailedWhenInputInvalid($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'password'); | |
$validator = Validator::make($data, $rules); | |
$passed = $validator->passes(); | |
$this->assertFalse($passed); | |
} | |
public function provideDataValidatePasswordFailedWhenInputInvalid() | |
{ | |
return [ | |
[[]], | |
[['password' => '']], | |
[['password' => ' ']], | |
[['password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH - 1)]], | |
]; | |
} | |
/** | |
* @param array $data Request data | |
* | |
* @dataProvider provideDataValidatePasswordSuccess | |
*/ | |
public function testValidatePasswordSuccess($data) | |
{ | |
$request = new RegisterRequest; | |
$rules = array_only($request->rules(), 'password'); | |
$validator = Validator::make($data, $rules); | |
$passed = $validator->passes(); | |
$this->assertTrue($passed); | |
} | |
public function provideDataValidatePasswordSuccess() | |
{ | |
return [ | |
[['password' => ' 12345678 ', 'password_confirmation' => ' 12345678 ']], | |
[ | |
[ | |
'password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH), | |
'password_confirmation' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH), | |
], | |
], | |
[ | |
[ | |
'password' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH + 1), | |
'password_confirmation' => str_repeat('a', RegisterRequest::PASSWORD_MIN_LENGTH + 1), | |
], | |
], | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment