Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Laravel resource

I am testing an API endpoint returned Laravel resource with pagination

 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),
        ]);
}

so my problem is the returned result is not the same because of the path of the endpoint is not equal to the returned of the resource.

This is the result returned from the endpoint:

"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
    }

This is the code returned from the resource ' $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,
          }

so how can I pass the endpoint to my code or how can I make them equal, and is there is a proper way to test Laravel resource?

like image 380
TheGeeky Avatar asked Oct 28 '25 10:10

TheGeeky


1 Answers

The answer lies in the JsonResource::response() method — this method accepts an optional Illuminate\Http\Request $request parameter, which will give context as to where you're trying to use the resource.

Calling $this->json('GET', '/api/customer/plans') will produce a Request object that looks something like this (heavily truncated for brevity):

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

Meanwhile, if no Request object is provided when resolving API resources, Laravel will create a new one using defaults, which will look more like this:

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

To make sure these match, you'll want to create a new Request object in your test case that looks something like what you're requesting, then pass it to the $resource->response() call:

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),
        ]);
}
like image 61
Steve Grunwell Avatar answered Oct 30 '25 01:10

Steve Grunwell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!