在测试控制器时是否有完全跳过授权的内置方法?
样本控制器:
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;
。
答案 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');
});