How to test Laravel Api (only) Controllers with PEST Php testing?

1.1k views Asked by At

I've setup a backend only Laravel app from the boilerplate. I want to test the API controllers using Pest, however, I keep getting Unresolvable dependency resolving [Parameter #0 [ <required> $request ]] in class Illuminate\Http\Client\Request.

// UserControllerTest.php

use App\Models\User;
use function Pest\Laravel\{getJson, actingAs};
use Illuminate\Foundation\Testing\RefreshDatabase;

// Necessary to access Laravel testing helpers and database factory stuff
uses(
    Tests\TestCase::class,
    RefreshDatabase::class
);

// Auto set up a new authed user for each test
beforeEach(function() {
    actingAs(User::factory()->create());
});

/**
 * Test that the user can be retrieved and api succeeds
 */
it('Test get user succeeds', function () {
    // Should get the user from the user controller
    $response = getJson('api/user');

    // Response should contain a user and be within the 200 range
    $response->assertStatus(200);
});

Below is the user controller, just returns the logged in user from the request.

UserController.php

    use Illuminate\Http\Client\Request;

    public function index(Request $request)
    {
        // Show the current logged in user
        $user = $request->user();

        return new UserResource($user);
    }

My return response is a 500 server error

  Failed asserting that 200 is identical to 500.
  
  The following exception occurred during the last request:
  
  Illuminate\Contracts\Container\BindingResolutionException: Unresolvable dependency resolving [Parameter #0 [ <required> $request ]] in class Illuminate\Http\Client\Request in /home/sites/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php:1118
  Stack trace:
  #0 /home/sites/my-app/vendor/laravel/framework/src/Illuminate/Container/Container.php(1027): Illuminate\Container\Container->unresolvablePrimitive(Object(ReflectionParameter))

Has anyone used Pestphp to test api only laravel controllers? Is there something that needs to be mocked to test an api route with PEST?

Edit

This Testing Laravel API with Pest article is quite similar in structure, where they'd just use the $response = $this->getJson("/api/posts/{$post->id}"); to get the JSON response, however they don't have the same issue as me.

API Route

Route::group(['middleware' => ['auth:sanctum']], function () {
    Route::apiResource('user', UserController::class);
}
//  GET|HEAD api/user =>user.index › UserController@index

Addition Tests

Seems it's due to there being no \Illuminate\Http\Client\Request $request when calling `getJson('api/user');

Trying to get a specific user, where there's no $request param in the controller works.

// This works fine. No error like above.
it('Test get user succeeds', function () {
    $user = User::factory()->create();

    // Should get the user from the user controller
    $response = getJson('api/user/' . $user->id);

    // Response should contain a user and be within the 200 range
    $response->assertStatus(200);
});

Versions

Laravel 9.19
1

There are 1 answers

0
wanna_coder101 On BEST ANSWER

Turns out the issue was I imported the incorrect Request $request class in my UserController

// Wrong Request Class
// use Illuminate\Http\Client\Request;

// Proper Request Class
use Illuminate\Http\Request;