I am trying to test signup for user in pest here is my pest code

test('signup user', function () {
    $response = $this->post('signup-user',[
        'email' => '[email protected]',
        'first_name' => 'vishal',
        'last_name' => 'singh',
        'password' => '111111',
        'confirm_password' => '111111'
    ]);
        
    $response->assertSessionHas('success', 'You have registered successfully');  
});

am getting this error
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testing.users' doesn't exist (Connection: mysql, SQL: select count(*) as aggregate from `users` where `email` = [email protected])   

  at D:\laravel-tailwind\laravelwithtailwind\tests\Feature\AppTest.php:36
     32▕         'password' => '111111',
     33▕         'confirm_password' => '111111'
     34▕     ]);
     35▕
  ➜  36▕     $response->assertSessionHas('success', 'You have registered successfully');
     37▕ });
     38▕

on docker all the containers are running well.and i have users table in my database,when i am testing someting related to data base or mysql am getting error

This is my signup_user function:

public function signupUser(Request $request) {
    $request->validate([
        'email'=>'required|email|unique:users',
        'first_name'=>'required', 
        'last_name'=>'required', 
        'password'=>'required|min:6|max:12', 
        'confirm_password'=>'required|min:6|max:12'
    ]);
    $user = new User(); 
    $user->email = $request->email; 
    $user->first_name = $request->first_name; 
    $user->last_name = $request->last_name; 
    $user->password = Hash::make($request->password); 
    $user->confirm_password = Hash::make($request->confirm_password);

I want to test this case:

test('user can signup', function () {
    $userData = [ 'email' => '[email protected]', 'first_name' => 'vishal', 'last_name' => 'singh', 'password' => '123123', 'confirm_password' => '123123', ];
    $this->post(route('signup-user'), $userData)
         ->assertSessionHas('success', 'You have registered successfully');
    $this->assertDatabaseHas('users', [ 'email' => '[email protected]', 'first_name' => 'vishal', 'last_name' => 'singh', ]);
});
2

There are 2 best solutions below

1
Vishal Kumar On

According to the Laravel documentation, Sail overrides the DB name you defined in the .env file when you run the tests. You need to remove the following line from your phpunit.xml file: it is solved now thankyou

0
w5m On

Laravel Sail creates a dedicated database named testing so that your tests are isolated from your main database and therefore don't interfere with the data within it (source: https://laravel.com/docs/11.x/sail#running-tests). Sail also modifies the phpunit.xml file in your project to point at this testing database when running tests, by adding this line of code...

<env name="DB_DATABASE" value="testing"/>

The error message you reported stated Base table or view not found: 1146 Table 'testing.users' doesn't exist.

If you examine the testing database (e.g. using MySQL Workbench) you will see that it is an empty database and this is consistent with the error message you receive i.e. no users table exists within the testing database. The fact that you have a users table in your main database is irrelevant as your Pest test is not set to look at your main database.

One solution is to remove the above line of code from your phpunit.xml file (as you have noted in your answer). However, I would NOT recommend this approach as your tests will pollute your main database and may inadvertently delete data you wanted to keep.

Clearly, if the testing database is empty, then migrations need to be run to create the appropriate tables prior to the test running. Helpfully, Pest provides a configuration option which, when enabled, will reset the database prior to each test. This essentially calls php artisan migrate:fresh on your testing database.

The best solution, therefore, is to edit your tests/Pest.php file and uncomment the line in the uses() function which binds the Illuminate\Foundation\Testing\RefreshDatabase class to your test functions:

/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "uses()" function to bind a different classes or traits.
|
*/

uses(
    Tests\TestCase::class,
    Illuminate\Foundation\Testing\RefreshDatabase::class,  // <- uncommented line
)->in('Feature');