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

mad*_*oet 2 php phpunit functional-testing laravel-5

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

示例控制器:

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]);
}
Run Code Online (Sandbox Code Playgroud)

我想跳过change-password规则,它是在里面定义的AuthServiceProvider

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

我不想添加smt。就像if (env('APP_ENV') == 'testing') return;在代码里面一样。

msd*_*msd 6

其实有一个内置的方式。您可以在实际授权检查之前添加要调用的“before”回调,只需返回即可绕过检查true

    \Gate::before(function () {
        return true;
    });
Run Code Online (Sandbox Code Playgroud)

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


Mat*_*aly 5

我不知道有什么,但您可以将该检查移至专用中间件,并使用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);
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*boc 5

来自 Laravel文档

测试应用程序时,您可能会发现为某些测试禁用中间件很方便。这将使您能够独立于任何中间件问题来测试您的路由和控制器。Laravel 包含一个简单的WithoutMiddleware特征,您可以使用它自动禁用测试类的所有中间件:

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

class ExampleTest extends TestCase
{
    use WithoutMiddleware;

    //
}
Run Code Online (Sandbox Code Playgroud)

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

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

    $this->visit('/')
         ->see('Laravel 5');
}
Run Code Online (Sandbox Code Playgroud)

PS:从 Laravel 5.1 开始