简体   繁体   English

Laravel Testing auth中间件

[英]Laravel Testing auth middleware

When feature testing my app, I find myself writing pretty much the same tests to verify that my controllers require authentication. 在对应用程序进行功能测试时,我发现自己编写了几乎相同的测试来验证我的控制器是否需要身份验证。 It usually looks something like this: 通常看起来像这样:

public function a_guest_cannot_view_any_of_the_pages()
{
    $this->withExceptionHandling();

    $model = factory(Model::class)->create();

    $response = $this->get(route('models.show', [ 'id' => $model->id ]));
    $response->assertRedirect(route('login'));

    $response = $this->get(route('models.edit', [ 'id' => $model->id ]));
    $response->assertRedirect(route('login'));

   ...etc 
}

However, I find it unnecessarily cumbersome to test it like this for every controller that requires authentication. 但是,我发现对每个需要身份验证的控制器进行这样的测试都不必要地麻烦。

Is there any tactics for testin CRUD with auth middleware? 使用身份验证中间件测试CRUD是否有任何策略? How do I improve this? 我该如何改善?

you can use a data provider: 您可以使用数据提供程序:

in tests/TestCase.php: 在tests / TestCase.php中:

/**
* @dataProvide dataProvider
*/
public function testRedirectToAuth($routeName)
    {
    $this->withExceptionHandling();

    $model = factory(Model::class)->create();

    $response = $this->get(route($routeName, [ 'id' => $model->id ]));
    $response->assertRedirect(route('login'));
}

and then you can call it in all the test cases: 然后您可以在所有测试用例中调用它:

public function dataProvider()
{
  return [
    'model.show',
    'model.edit',
    ...
  ];
}

Solution 1 Define the middleware in the controller constructor that will act on all functions 解决方案1在控制器构造函数中定义将对所有功能起作用的中间件

public function __construct()
{
    $this->middleware('auth');
}

ou Solution 2 Define the middleware directly on the route 解决方案2在路径上直接定义中间件

Route::get('admin/profile', function () {
    //
})->middleware('auth');

https://laravel.com/docs/5.7/middleware https://laravel.com/docs/5.7/middleware

You could use a ShowTrait , when using this trait you have to specify your route and model name. 您可以使用ShowTrait ,使用此特征时,您必须指定您的路线和模型名称。

<?php

class ModelTest extends Test
{
    use ShowTrait;

    protected $routebase = 'api.v1.models.';
    protected $model = Model::class;
}

abstract class Test extends TestCase
{
    use RefreshDatabase, InteractsWithDatabase, UseAuthentication;

    protected $routebase = 'api.v1.';
    protected $model;

    /**
     * @test
     */
    public function is_valid_model()
    {
        $this->assertTrue(class_exists($this->model));
    }
}

trait ShowTrait {

    public function test_show_as_authenticated_user()
    {
        $record = factory($this->model);

        $this->assertShow($record)
    }


    protected function assertShow($record)
    {
        $route = route($this->routebase . "show", ['id' => $record->id]);

        // Get response
        $response = $this->get($route);
        $response->assertRedirect(route('login'));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM