【问题标题】:laravel testing web routeslaravel 测试网络路由
【发布时间】:2022-02-08 14:34:46
【问题描述】:

我有一个制造模块的网络路由(处理资源的支持路由)

Route::resource('/admin/manufactures', App\Http\Controllers\Back\ManufacturerController::class);

我已经创建了一个带有简单规则名称的 ManufacturerRequest=>必需

我想使用 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,但除此之外,store 方法采用制造商请求对象来处理验证,并且在测试的情况下,我传递了一个数组,因为它只接受数组。

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

【问题讨论】:

    标签: laravel phpunit


    【解决方案1】:

    您想要做的事情非常简单,并且在Documentation 上也有说明,您必须完整阅读文档,这样您才能大致了解您可以使用该框架做什么,特别是因为您是新的。

    由于您没有指定您使用的版本,我将使用 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();,因为框架会自动解析 FormRequestauthorizevalidate。如果您阅读了validate 的部分说明,您会看到:

    那么,如何评估验证规则?您需要做的就是在控制器方法上输入提示请求。 在调用控制器方法之前验证传入的表单请求,这意味着您无需使用任何验证逻辑来​​弄乱您的控制器。

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

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

    public function store(ManufacturerRequest $request)
    {
        //db
    
        Manufacturer::create($request->validated());
    }
    

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

    在你尝试任何事情之前,我建议你阅读这篇文章中的my answer,这样你就可以更清楚地了解测试。

    所以,您收到 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],
        ];
    }
    

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

    • 我已经测试了正常插入是否有效,是否正在检查是否输入了有效名称(FormRequest 规则),如果用户未登录,则应该引发未经授权的异常。
    • 我使用了@depends,仅在依赖测试通过时才运行测试,这样我们就可以防止因为正常流程没有成功而运行“负面”测试,所以运行没有意义其他的也得到“测试未通过”。
    • 我还使用了@dataProvider,它用于与测试共享数据,因此无需多次复制粘贴测试并导致数据变化,您只需更改希望测试使用的数据即可。

    【讨论】:

      猜你喜欢
      • 2020-06-18
      • 2021-09-30
      • 1970-01-01
      • 2021-11-24
      • 2023-03-23
      • 2019-10-16
      • 2019-09-20
      • 2019-11-15
      • 2018-05-07
      相关资源
      最近更新 更多