我有一个用于制造模块(处理资源的后台路由)的web路由。
Route::resource('/admin/manufactures', App\Http\Controllers\Back\ManufacturerController::class);我创建了一个带有简单规则ManufacturerRequest的name=>required
我想使用Laravel来测试资源(CRUD)
在我的控制器中,存储方法如下所示
public function store(ManufacturerRequest $request)
{
//db
$request->validate();
Manufacturer::create($request->all());
}我有个简单的测试
$response = $this->post('/admin/manufactures' ,
[
'_token' => csrf_token(),
'name' => 'test'
]);
$response->assertStatus(200);它是返回403,但是除了存储方法接受处理验证的ManufacturerRequest对象之外,在测试的情况下,我通过了一个数组,因为它只接受数组。
那么,我如何创建一个“模拟”表单并将请求传递给控制器的测试,以便测试验证和CRUD
发布于 2022-02-05 03:15:42
您想要做的事情非常简单,并且在文档上也有解释,非常重要的是要全面阅读文档,以便您对框架可以做什么有一个大致的概念,特别是因为您对它是新的。
由于您没有指定您使用的版本,我将使用Laravel 8,但它几乎是相同的。
根据您的代码:
资源路由
Route::resource('/admin/manufactures', ManufacturerController::class);控制器
public function store(ManufacturerRequest $request)
{
//db
$request->validate();
Manufacturer::create($request->all());
}您需要将控制器更改为:
public function store(ManufacturerRequest $request)
{
//db
Manufacturer::create($request->all());
}是的,只要删除$request->validate();就可以了,因为框架将自动解决FormRequest、授权和验证。如果您阅读了validate部分解释,您将看到以下内容:
那么,验证规则是如何评估的呢?您需要做的就是在控制器方法上键入提示请求。传入的表单请求在控制器方法被称为之前进行验证,这意味着您不需要用任何验证逻辑干扰控制器。
因此,当运行控制器的第一行时,这意味着FormRequest通过了授权检查并验证了输入。
您还可以在控制器上更新的是:
public function store(ManufacturerRequest $request)
{
//db
Manufacturer::create($request->validated());
}请看我已经用$request->validated()更改了$request->validated(),validated只会返回您在FormRequest的rules上有一个键的字段,如果您使用all,您将传递请求中的所有内容(也会传递未经验证的数据,这是不好的)。
在尝试之前,我建议您在这篇文章中阅读我的回答,这样您就可以更清楚地了解测试。
所以,您将得到一个403,可能是因为您有一个中间件要求您登录,而您没有使用$this->actingAs()。
仅仅因为您没有分享FormRequest规则,我就给出一个非常小的例子。如果您的内部有此规则:
'name' => ['required', 'string'],您可以做的测试是:
public function test_manufacturer_is_created(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->post('/admin/manufactures', ['name' => $name = 'Manufacturer 1']);
$response->assertSuccessful();
$this->assertDatabaseHas(
'manufacturers',
[
'name' => $name
]
);
}
/**
* @depends test_manufacturer_is_created
*/
public function test_unauthorized_error_is_thrown_when_the_user_is_not_logged_in(): void
{
$response = $this->post('/admin/manufactures', ['name' => 'Manufacturer 1']);
$response->assertUnauthorized();
}
/**
* @depends test_manufacturer_is_created
* @dataProvider invalidDataProvider
*/
public function test_error_should_be_returned_when_invalid_data_is_sent($value, bool $deleteField): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->post(
'/admin/manufactures',
! $deleteField ? ['name' => $value] : []
);
$response->assertInvalid(['name']);
}
public function invalidDataProvider(): array
{
return [
'Missing name' => [null, true],
'Empty name' => ['', false],
'Null name' => [null, false],
'Array name' => [[], false],
'Number name' => [123, false],
'Boolean name' => [true, false],
];
}请记住,我在这里使用了很多东西:
@depends,它只用于在依赖测试通过时才运行测试,这样我们就可以防止仅仅因为正常流没有成功而运行“负”测试,所以运行其他测试没有意义,也没有得到“测试没有通过”。@dataProvider,它用于与测试共享数据,因此,与其多次使用数据变化复制粘贴测试,不如改变您希望测试使用的数据。https://stackoverflow.com/questions/70988672
复制相似问题