Laravel sail - test returns error: Target Class RestApiController does not exist

I get error that controller does not exist, but it exists

Route:

Route::middleware(['check.team.role'])->group(function () {
...
Route::get('/api/v1/folder/{folder}', 'App\Http\Controllers\RestApiController@getFolderById');
...
});

Controller app/Http/Controllers/RestApiController.php


namespace App\Http\Controllers;

use App\Models\AccessMaterial;
use App\Models\User;
use App\Models\Team;
...

class RestApiController extends Controller
{
    protected $noteService;
    protected $taskService;
    protected $voteService;
    protected $CourseService;
    protected $teamService;
    protected $teamId;

    
    public function __construct(NoteService $noteService, TaskService $taskService, VoteService $voteService, CourseService $courseService, TeamService $teamService)
    {
        
    $this->middleware('auth.custom_sanctum');
        
        $this->noteService = $noteService;
        $this->taskService = $taskService;
        $this->voteService = $voteService;
        $this->courseService = $courseService;
        $this->teamService = $teamService;
    $this->teamId = Team::requested() ? Team::requested()->id : null;
                
        
    }
...

    public function getFolderById(UserFolder $folder) {
        
        try {
        
            $folder = UserFolder::findOrFail($folder->id);
            
            if($folder->team_id != $this->teamId) {
                return response()->json(['success' => false, 'message' => 'Team error'], 403);
            }
            
            
            $notes_ids = UserNote::where('folder_id', $folder->id)->pluck('id')->toArray();
            $tasks_ids = UserTask::where('folder_id', $folder->id)->pluck('id')->toArray();
            $votes_ids = UserVote::where('folder_id', $folder->id)->pluck('id')->toArray();
            $folder->notes = $notes_ids;
            $folder->tasks = $tasks_ids;
            $folder->votes = $votes_ids;
            
            $courses_ids = Course::where('folder_id',$folder->id)->where('user_id','!=',null)->pluck('id')->toArray();
            $folder->courses = $courses_ids;

            
            return response()->json(['success'=>true,'folder'=>$folder]);
            
        } catch (ModelNotFoundException $e) {
            return response()->json(['success' => false, 'message' => 'Folder not found'], 404);
        }
    }
...
}

test:


namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

use Illuminate\Support\Str;

use App\Models\User;
use App\Models\UserFolder;
use App\Models\UserNote;
use App\Models\UserTask;
use App\Models\UserVote;
use App\Models\Course;
use App\Models\Team;

use Illuminate\Database\Eloquent\Factories\Factory;
use Database\Factories\UserFactory;
use Database\Factories\TeamFactory;
use Database\Factories\UserTaskFactory;
use Database\Factories\UserFolderFactory;
use Database\Factories\UserNoteFactory;
use Database\Factories\UserVoteFactory;
use Database\Factories\CourseFactory;

class RestApiOtherTest extends TestCase
{
    use RefreshDatabase;
    
    public function testServerResponse()
    {
        $user = \Database\Factories\UserFactory::new()->create();
        $teamA = Team::factory()->create();
        $teamA->users()->attach($user->id,['role'=>'hr']);
        $this->actingAs($user);

      
        $folder = UserFolder::factory()->create();

        $note = UserNote::factory()->create(['folder_id' => $folder->id]);
    

        $response = $this->getJson("/api/v1/folder/{$folder->id}");
        $response->assertStatus(200);
        $response->assertJson(['success' => true]);

    }   
...
}

when i make test: ./vendor/bin/sail test i get error:

[2024-04-06 11:36:43] local.ERROR: Target class [App\Http\Controllers\RestApiController] does not exist. {"userId":"9bbdffa8-b3f8-4980-834b-0a667dcedc32","exception":"[object] (Illuminate\Contracts\Container\BindingResolutionException(code: 0): Target class [App\Http\Controllers\RestApiController] does not exist. at /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:914) [stacktrace] #0 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(795): Illuminate\Container\Container->build() #1 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(957): Illuminate\Container\Container->resolve() #2 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(731): Illuminate\Foundation\Application->resolve() #3 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(942): Illuminate\Container\Container->make() ...

I tried to run ./vendor/bin/sail test and i was expecting that test will be passed but i get 500 error that controller class not found

UPDATED 1

i found out that if i use

use PHPUnit\Framework\TestCase;

instead of

use Tests\TestCase

i get another error:

  FAILED  Tests\Feature\RestApiOtherTest > server response                                                                                   Error
  Call to a member function connection() on null

  at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1819
    1815▕      * @return \Illuminate\Database\Connection
    1816▕      */
    1817▕     public static function resolveConnection($connection = null)
    1818▕     {
  ➜ 1819▕         return static::$resolver->connection($connection);
    1820▕     }
    1821▕
    1822▕     /**
    1823▕      * Get the connection resolver instance.

      +13 vendor frames
  14  tests/Feature/RestApiOtherTest.php:37

i think this is something wrong with factory? but do not what exact

Upvotes: 0

Views: 88

Answers (1)

matiaslauriti
matiaslauriti

Reputation: 8082

Your fix should be to define routes like this:

Route::get(
    '/api/v1/folder/{folder}', 
    [\App\Http\Controllers\RestApiController::class, 'getFolderById'],
);

Laravel stopped using 'App\Http\Controllers\RestApiController@getFolderById' as a definition of class and method to use on a route definition since Laravel 8.x+, check Laravel 10.x documentation about it.

Last tip, everytime you need to have Laravel or any feature of it available inside a test, you must use Tests\TestCase, not PHPUnit\Framework\TestCase. If you use the last one mentioned, you will never load Laravel, so nothing that needs/uses Laravel will work.

Upvotes: 0

Related Questions