php 在功能测试Laravel应用程序时跳过授权

k5hmc34c  于 2023-10-15  发布在  PHP
关注(0)|答案(5)|浏览(136)

在测试控制器时,是否有一种内置的方法可以完全跳过授权?
样品控制器:

public function changePassword(Request $request, LdapInterface $ldap)
{
    $this->authorize('change-password');

    $this->validate($request, [
        'pass' => 'min:8|confirmed|weakpass|required', 
    ]);

    $success = $ldap->updatePassword($request->get('pass'));

    $message = $success ?
        'Your e-mail password has been successfully changed' :
        'An error occured while trying to change your alumni e-mail password.';

    return response()->json(['message' => $message]);
}

我想跳过change-password规则,它在AuthServiceProvider中定义如下:

public function boot(GateContract $gate)
{
    $gate->define('change-password', function ($user) {
        // Some complex logic here
    });
}

我不想添加SMT。比如代码中的if (env('APP_ENV') == 'testing') return;

pw136qt2

pw136qt21#

实际上,有一种内在的方式。您可以添加一个before回调,在实际授权检查之前调用,并通过返回true来绕过检查:

\Gate::before(function () {
    return true;
});

您应该将此代码片段添加到测试的setUp方法或您想要绕过授权的每个测试方法中。

qyuhtwio

qyuhtwio2#

我不知道有哪一个,但是您可以将该检查移动到专用的中间件,并在测试中使用withoutMiddleware trait禁用它。
或者可以使用Mockery模拟应用程序的gate示例。Mockery有很好的文档记录,所以我建议阅读文档以了解更多细节,但设置它看起来像这样:

$mock = Mockery::mock('Illuminate\Contracts\Auth\Access\Gate');
$mock->shouldReceive('authorize')->with('change-password')->once()->andReturn(true);
$this->app->instance('Illuminate\Contracts\Auth\Access\Gate', $mock);

这将设置一个gate合约的mock,设置它期望接收的内容以及它应该如何响应,然后将其注入应用程序。

watbbzwu

watbbzwu3#

Laravel文档:
在测试应用程序时,您可能会发现为某些测试禁用中间件很方便。这将允许您在隔离任何中间件问题的情况下测试路由和控制器。Laravel包含一个简单的WithoutMiddleware trait,你可以使用它来自动禁用测试类的所有中间件:

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use WithoutMiddleware;

    //
}

或者你可以在测试方法中使用withoutMiddleware()方法,如下所示:

public function testBasicExample()
{
    $this->withoutMiddleware();

    $this->visit('/')
         ->see('Laravel 5');
}

PS:Laravel 5.1以后

brjng4g3

brjng4g34#

在我的测试中,我添加了一个方法,我可以在测试开始时调用该方法来禁用仅针对该测试的授权。
添加到基本测试类

public function withoutAuthorization()
{
    \Gate::before(function () {
        return true;
    });

    return $this;
}

在测试中,你可以称之为:

public function testSomeThing()
{
    $this->withoutAuthorization();

    // any gates will be bypassed
    $this->get('/my-protected-endpoint');
}
mm9b1k5b

mm9b1k5b5#

它简单得多。只需将其从路由文件中的授权要求部分中取出即可。在这个例子中,我需要AssignmentsController在没有身份验证的情况下工作,所以我只是将它从jwt.auth组上移:

Route::post('v1/auth/login', 'Api\AuthController@authenticate');
Route::post('v1/auth/sendpassword', 'Api\AuthController@sendPassword');
Route::get('v1/assignments', 'Api\AssignmentsController@getAll');

Route::group(['middleware' => 'jwt.auth'], function() {
  Route::post('v1/auth/logout', 'Api\AuthController@logout');
  Route::post('v1/shipments', 'Api\ShipmentController@getShipments');
  Route::post('v1/assignments/{id}/transfer', 'Api\AssignmentsController@saveAssignment');
  Route::get('v1/shipments/assignments/{assignmentId}', 'Api\AssignmentsController@getDetail');
  Route::post('v1/shipments/assignments/{id}/upload', 'Api\AssignmentsController@uploadFile');
});

相关问题