さまざまなカスタムFormRequest
入力をユニットテストしようとしています。私は次の解決策を見つけました:
$this->call(…)
メソッドの使用を提案し、期待値 (回答へのリンク) を使用してresponse
をアサートします。 RoutingおよびControllersに直接依存するため、これはやりすぎです。
Laravel Frameworkからのテイラーのテスト found /tests/Foundation/FoundationFormRequestTest.php
。そこには多くのモックとオーバーヘッドがあります。
ルールに対して個々のフィールド入力をユニットテストできるソリューションを探しています(同じリクエスト内の他のフィールドから独立しています)。
サンプルFormRequest:
public function rules()
{
return [
'first_name' => 'required|between:2,50|alpha',
'last_name' => 'required|between:2,50|alpha',
'email' => 'required|email|unique:users,email',
'username' => 'required|between:6,50|alpha_num|unique:users,username',
'password' => 'required|between:8,50|alpha_num|confirmed',
];
}
必要なテスト:
public function testFirstNameField()
{
// assertFalse, required
// ...
// assertTrue, required
// ...
// assertFalse, between
// ...
}
public function testLastNameField()
{
// ...
}
どのようにすれば単体テスト(assert)で各フィールドの各検証ルールを単体テストできますか?
Laracast で良い解決策を見つけ、ミックスにいくつかのカスタマイズを追加しました。
コード
public function setUp()
{
parent::setUp();
$this->rules = (new UserStoreRequest())->rules();
$this->validator = $this->app['validator'];
}
/** @test */
public function valid_first_name()
{
$this->assertTrue($this->validateField('first_name', 'jon'));
$this->assertTrue($this->validateField('first_name', 'jo'));
$this->assertFalse($this->validateField('first_name', 'j'));
$this->assertFalse($this->validateField('first_name', ''));
$this->assertFalse($this->validateField('first_name', '1'));
$this->assertFalse($this->validateField('first_name', 'jon1'));
}
protected function getFieldValidator($field, $value)
{
return $this->validator->make(
[$field => $value],
[$field => $this->rules[$field]]
);
}
protected function validateField($field, $value)
{
return $this->getFieldValidator($field, $value)->passes();
}
更新
同じ問題に対してe2eアプローチがあります。確認するデータを[〜#〜] [〜#〜]対象のルートに送信し、応答にセッションが含まれているかどうかを確認できますエラー。
$response = $this->json('POST',
'/route_in_question',
['first_name' => 'S']
);
$response->assertSessionHasErrors(['first_name');
フレンド、ユニットテストを正しく行ってください。結局のところ、ここでテストしているのはrules
だけではなく、validationData
関数とwithValidator
関数も存在する可能性があります。
これはどのように行われるべきかです:
<?php
namespace Tests\Unit;
use App\Http\Requests\AddressesRequest;
use App\Models\Country;
use Faker\Factory as FakerFactory;
use Illuminate\Routing\Redirector;
use Illuminate\Validation\ValidationException;
use Tests\TestCase;
use function app;
use function str_random;
class AddressesRequestTest extends TestCase
{
public function test_AddressesRequest_empty()
{
try {
//app(AddressesRequest::class);
$request = new AddressesRequest([]);
$request
->setContainer(app())
->setRedirector(app(Redirector::class))
->validateResolved();
} catch (ValidationException $ex) {
}
//\Log::debug(print_r($ex->errors(), true));
$this->assertTrue(isset($ex));
$this->assertTrue(array_key_exists('the_address', $ex->errors()));
$this->assertTrue(array_key_exists('the_address.billing', $ex->errors()));
}
public function test_AddressesRequest_success_billing_only()
{
$faker = FakerFactory::create();
$param = [
'the_address' => [
'billing' => [
'Zip' => $faker->postcode,
'phone' => $faker->phoneNumber,
'country_id' => $faker->numberBetween(1, Country::count()),
'state' => $faker->state,
'state_code' => str_random(2),
'city' => $faker->city,
'address' => $faker->buildingNumber . ' ' . $faker->streetName,
'suite' => $faker->secondaryAddress,
]
]
];
try {
//app(AddressesRequest::class);
$request = new AddressesRequest($param);
$request
->setContainer(app())
->setRedirector(app(Redirector::class))
->validateResolved();
} catch (ValidationException $ex) {
}
$this->assertFalse(isset($ex));
}
}