2

我正在使用分页测试 API 端点返回的 Laravel 资源

 public function test_showing_all_plans(): void
 {
    $plans = Plan::where('is_active', true)
        ->paginate(10);

    $resource = PlansResource::collection($plans);

    $this->withHeaders([
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
        'AppKey' => 5,
    ])
        ->json('GET', '/api/customer/plans')
        ->assertStatus(200)
        ->assertExactJson([
            $resource->response()->getData(true),
        ]);
}

所以我的问题是返回的结果不一样,因为端点的路径不等于资源的返回。

这是从端点返回的结果:

"links": {
        "first": "http://www.site.local/api/customer/plans?page=1",
        "last": "http://www.site.local/api/customer/plans?page=3",
        "next": "http://www.site.local/api/customer/plans?page=2",
        "prev": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "http://www.site.local/api/customer/plans",
        "per_page": 10,
        "to": 10,
        "total": 24
    }

这是从资源“ $resource->response()->getData(true)”返回的代码

 "links": {
            "first": "http://www.site.local?page=1",
            "last": "http://www.site.local?page=3",
            "next": "http://www.site.local?page=2",
            "prev": null
        },
        "meta": {
            "current_page": 1,
            "from": 1,
            "last_page": 3,
            "path": "http://www.site.local",
            "per_page": 10,
            "to": 10,
          }

那么如何将端点传递给我的代码,或者如何使它们相等,是否有正确的方法来测试 Laravel 资源?

4

1 回答 1

8

答案在于JsonResource::response()方法——这个方法接受一个可选Illuminate\Http\Request $request参数,它会给出你试图在哪里使用资源的上下文。

调用$this->json('GET', '/api/customer/plans')将产生一个看起来像这样的 Request 对象(为简洁起见,被大量截断):

Illuminate\Http\Request {
  pathInfo: "/api/customer/plans"
  requestUri: "/api/customer/plans"
  method: "GET"
}

同时,如果在解析 API 资源时没有提供 Request 对象,Laravel 将使用默认值创建一个新对象,看起来更像这样:

Illuminate\Http\Request {
  pathInfo: "/"
  requestUri: "/"
  method: "GET"
}

为了确保这些匹配,您需要在测试用例中创建一个新的 Request 对象,看起来像您请求的内容,然后将其传递给$resource->response()调用:

use Illuminate\Http\Request;

public function test_showing_all_plans(): void
 {
    $plans    = Plan::where('is_active', true)->paginate(10);
    $resource = PlansResource::collection($plans);
    $request  = Request::create('/api/customer/plans', 'GET');

    $this->getJson('/api/customer/plans', [
         'AppKey' => 5,
       ])
        ->assertStatus(200)
        ->assertExactJson([
            $resource->response($request)->getData(true),
        ]);
}
于 2020-05-22T17:39:06.397 回答