使用依赖注入和自定义请求测试 Laravel API 资源

Testing Laravel API resources with dependency injections and custom requests

类型提示的路由参数在从测试中调用时不会实例化。

我有一个 Laravel API 资源 Route::apiResource('users', 'Api\UserController');

这是我在控制器中的更新方法:

public function update(UpdateUserRequest $request, User $user)
{
    //
}

在 UpdateUserRequest 中:

public function rules()
{
    dd($this->route("user"));
}

如果我从 Postman 调用这个端点,我会得到完整的 user 对象。但是,如果我从测试中调用它:

    $response = $this->actingAs($this->user)->
        json('POST', '/api/users/'.$this->user->id, [
            '_method' => 'PUT',
            'data' => [
                // ...
            ]
        ]);

我只是得到字符串“1”,而不是实例化的用户对象。

好吧,有一件事奏效了,我不知道这是正确的还是 "Laravel" 做事的方式是在自定义请求构造函数中强制实例化模型,并绑定测试中的实例:

在 UpdateUserRequest 中:

private $user;

public function __construct(User $user)
{
    $this->user = $user;
}

测试中:

$this->user = factory(\App\Models\User::class)->create();
$this->app->instance(\App\Models\User::class, $this->user);

这可能是由于您的测试用例使用了 \Illuminate\Foundation\Testing\WithoutMiddleware 特征。

为了后代,如果有人遇到这个问题,路由模型绑定由 \Illuminate\Routing\MiddlewareSubstituteBindings 中间件执行。 WithoutMiddleware 特性因此阻止了它 运行.

基础 Laravel 测试用例通过 /Illuminate/Foundation/Testing/WithoutMiddleware 提供了一个未记录的 withoutMiddleware() 方法,您可以使用它来解决这个问题,但是可能值得注意的是 Laravel、Taylor Otwell,recommends 尽可能使用所有中间件进行测试。