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

时间:2017-10-30 14:07:38

标签: php laravel-5 phpunit functional-testing

在测试控制器时是否有完全跳过授权的内置方法?

样本控制器:

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;

5 个答案:

答案 0 :(得分:2)

我不知道一个,但您可以将该检查移至专用中间件并使用withoutMiddleware特征在测试中禁用它。

或者您可以使用Mockery模拟应用程序的门实例。 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);

这将设置门限合约的模拟,设置它预期接收的内容以及它应如何响应,然后将其注入应用程序。

答案 1 :(得分:1)

来自laravel documentation

  

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

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以来

答案 2 :(得分:1)

实际上有一种内置方式。您可以在实际授权检查之前添加“之前”回调,只需返回true即可绕过检查:

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

您应该将此代码段添加到测试的setUp()方法或要通过授权的每种测试方法。

答案 3 :(得分:0)

在测试中,我添加了可以在测试开始时调用的方法,以仅针对该测试禁用授权。

添加到基础测试课程

<a onclick='openWindowWithConfirm("https://www.google.co.in")'>Click Me</a>

然后在测试中可以将其称为:

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

    return $this;
}

答案 4 :(得分:-1)

这简单得多。 只需将其从路径文件中的授权要求部分中取出即可。 在这个例子中,我需要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');
});