Laravel/PHPUnit 的 Github 操作错误

Error in Github Action for Laravel / PHPUnit

我使用 PHPUnit 进行 laravel unit/feature 测试的 github 操作出现错误。我的测试在本地通过。这是错误:

1) Tests\Feature\ClientControllerTest::test_clients_index_page_is_rendered
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL column with default value NULL (SQL: alter table "users" add column "role_id" integer not null)

可能是我没有完全理解测试的工作方式,但我正在使用内存中的 sqllite 数据库进行测试。我有一个针对用户 table 的迁移,然后是在创建角色 table 之后向用户 table 添加 role_id 的另一个迁移。

不理解为什么在 test_clients_index_page_is_rendered 测试期间出现错误,因为此时数据库应该已经启动并填充。

我不知道是不是因为角色 table 没有填充数据,它是用户 table 的外键。我认为这也会在本地失败,因为我仍在使用内存数据库。我有一个播种机来填充角色,但我不会在测试中的任何地方调用它。不确定我是否需要这样做,或者在哪里做?

这里是错误中提到的测试:

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Role;
use App\Models\User;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ClientControllerTest extends TestCase
{
    use RefreshDatabase;

    protected $user;

    public function setup() :void
    {
        parent::setUp();
        $this->user = User::factory()->create();
    }

    public function test_clients_index_page_is_rendered()
    {
        $this->actingAs($this->user);
        $response = $this->get('/clients');
        $response->assertStatus(200);
    }

以下是我认为也可能导致问题的相关迁移:

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('first_name');
            $table->string('last_name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();
        });
    }
}

然后添加角色table,然后是外键:

 Schema::table('users', function (Blueprint $table) {
            $table->foreignIdFor(Role::class)->after('password');
        });

我什至不知道如何解决这个问题,因为它在本地发生。任何帮助将不胜感激。

如果有帮助,请查看完整跟踪:

1) Tests\Feature\ClientControllerTest::test_clients_index_page_is_rendered
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL column with default value NULL (SQL: alter table "users" add column "role_id" integer not null)

/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Connection.php:705
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Connection.php:665
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Connection.php:495
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php:109
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php:363
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php:210
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:261
/home/runner/work/momentum/momentum/database/migrations/2022_01_01_222316_add_role_id_to_users_table.php:19
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:394
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:403
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:202
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:167
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:112
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php:85
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:585
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php:94
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:36
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Container/Util.php:40
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:93
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:37
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Container/Container.php:653
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Console/Command.php:136
/home/runner/work/momentum/momentum/vendor/symfony/console/Command/Command.php:298
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Console/Command.php:121
/home/runner/work/momentum/momentum/vendor/symfony/console/Application.php:1005
/home/runner/work/momentum/momentum/vendor/symfony/console/Application.php:299
/home/runner/work/momentum/momentum/vendor/symfony/console/Application.php:171
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Console/Application.php:94
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Console/Application.php:186
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:263
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Testing/PendingCommand.php:260
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Testing/PendingCommand.php:413
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:66
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:45
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:20
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:122
/home/runner/work/momentum/momentum/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:91
/home/runner/work/momentum/momentum/tests/Feature/ClientControllerTest.php:19

Caused by
PDOException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL column with default value NULL

更新

添加我的用户工厂:

namespace Database\Factories;

use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Factories\Factory;


class UserFactory extends Factory
{
    public function definition()
    {
        return [
            'first_name' => $this->faker->firstName,
            'last_name' => $this->faker->lastName,
            'phone' => $this->faker->unique()->numerify('###-###-####'),
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => 'yIXUNpkjO0rOQ5byMi', 
            'remember_token' => Str::random(10),
            'role_id' => rand(1,4)
        ];
    }
}

如您在堆栈跟踪中所见,在迁移步骤中抛出异常。

发生这种情况是因为您将 not null 列添加到 table,这通常是不可能的。 SQLite 不知道应该为 table 中已有的记录设置什么值 role_id,因此它会阻止您执行此操作。

您可以将默认值添加到 role_id,或将其移至初始迁移。