首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >laravel测试网络路径

laravel测试网络路径
EN

Stack Overflow用户
提问于 2022-02-04 15:12:42
回答 1查看 435关注 0票数 -2

我有一个用于制造模块(处理资源的后台路由)的web路由。

代码语言:javascript
复制
Route::resource('/admin/manufactures', App\Http\Controllers\Back\ManufacturerController::class);

我创建了一个带有简单规则ManufacturerRequest的name=>required

我想使用Laravel来测试资源(CRUD)

在我的控制器中,存储方法如下所示

代码语言:javascript
复制
public function store(ManufacturerRequest $request)
{
        //db
        $request->validate();

        Manufacturer::create($request->all());
 }

我有个简单的测试

代码语言:javascript
复制
$response = $this->post('/admin/manufactures' ,
[
   '_token' => csrf_token(),
   'name'   => 'test'
]);
       

$response->assertStatus(200);

它是返回403,但是除了存储方法接受处理验证的ManufacturerRequest对象之外,在测试的情况下,我通过了一个数组,因为它只接受数组。

那么,我如何创建一个“模拟”表单并将请求传递给控制器的测试,以便测试验证和CRUD

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-05 03:15:42

您想要做的事情非常简单,并且在文档上也有解释,非常重要的是要全面阅读文档,以便您对框架可以做什么有一个大致的概念,特别是因为您对它是新的。

由于您没有指定您使用的版本,我将使用Laravel 8,但它几乎是相同的。

根据您的代码:

资源路由

代码语言:javascript
复制
Route::resource('/admin/manufactures', ManufacturerController::class);

控制器

代码语言:javascript
复制
public function store(ManufacturerRequest $request)
{
    //db
    $request->validate();

    Manufacturer::create($request->all());
}

您需要将控制器更改为:

代码语言:javascript
复制
public function store(ManufacturerRequest $request)
{
    //db

    Manufacturer::create($request->all());
}

是的,只要删除$request->validate();就可以了,因为框架将自动解决FormRequest授权验证。如果您阅读了validate部分解释,您将看到以下内容:

那么,验证规则是如何评估的呢?您需要做的就是在控制器方法上键入提示请求。传入的表单请求在控制器方法被称为之前进行验证,这意味着您不需要用任何验证逻辑干扰控制器。

因此,当运行控制器的第一行时,这意味着FormRequest通过了授权检查并验证了输入。

您还可以在控制器上更新的是:

代码语言:javascript
复制
public function store(ManufacturerRequest $request)
{
    //db

    Manufacturer::create($request->validated());
}

请看我已经用$request->validated()更改了$request->validated()validated只会返回您在FormRequest的rules上有一个键的字段,如果您使用all,您将传递请求中的所有内容(也会传递未经验证的数据,这是不好的)。

在尝试之前,我建议您在这篇文章中阅读我的回答,这样您就可以更清楚地了解测试。

所以,您将得到一个403,可能是因为您有一个中间件要求您登录,而您没有使用$this->actingAs()

仅仅因为您没有分享FormRequest规则,我就给出一个非常小的例子。如果您的内部有此规则:

代码语言:javascript
复制
'name' => ['required', 'string'],

您可以做的测试是:

代码语言:javascript
复制
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],
    ];
}

请记住,我在这里使用了很多东西:

  • 我已经测试了正常插入是否有效,如果它正在检查一个有效的名称是输入(FormRequest规则),如果用户没有登录,它应该抛出一个未经授权的异常。
  • 我使用了@depends,它只用于在依赖测试通过时才运行测试,这样我们就可以防止仅仅因为正常流没有成功而运行“负”测试,所以运行其他测试没有意义,也没有得到“测试没有通过”。
  • 我还使用了@dataProvider,它用于与测试共享数据,因此,与其多次使用数据变化复制粘贴测试,不如改变您希望测试使用的数据。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70988672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档