The issue you're encountering with the integrity constraint violation on a nullable field in SQLite is likely due to how SQLite handles foreign keys and null values. In SQLite, a foreign key constraint is not enforced if the foreign key column is null, which should allow you to have a null value in the parent_id column. However, there might be a configuration or migration issue causing this problem.
Here are a few steps to troubleshoot and resolve the issue:
-
Check Migration for Foreign Key Constraint: Ensure that your migration file correctly specifies the
nullableforeign key constraint. It seems like you've done this, but double-check for any typos or misconfigurations.$table->foreignId('parent_id')->nullable()->constrained('tags')->cascadeOnDelete(); -
Verify Foreign Key Support in SQLite: You've already enabled foreign key support in your
pest.phpfile withPRAGMA foreign_keys=ON;. Ensure this is executed before any database operations in your tests. -
Check Factory Definitions: Ensure that your factory definitions for the
Tagmodel correctly handle theparent_idfield. If you're using Laravel factories, make sure theparent_idis set tonullby default or explicitly set it in your test. -
Test Database Schema: Sometimes, the in-memory SQLite database schema might not match your expectations. You can dump the schema to verify it:
DB::connection()->getPdo()->sqliteCreateFunction('schema', function () { return DB::select('SELECT sql FROM sqlite_master WHERE type="table"'); });Run this in a test to see the actual schema being used.
-
Check for Test Isolation Issues: Ensure that your tests are isolated and that the database is being refreshed correctly between tests. The
RefreshDatabasetrait should handle this, but verify that it's working as expected. -
Debugging: Add some debugging statements in your test to log the SQL queries being executed. This can help identify if there's an unexpected query causing the issue.
DB::listen(function ($query) { logger($query->sql, $query->bindings); }); -
Update SQLite Version: Ensure that your SQLite version is up-to-date, as older versions might have different behavior regarding foreign keys.
If after these steps the issue persists, consider simplifying the test case to isolate the problem further. For example, try creating a Tag with a null parent_id outside of the test context to see if the issue is specific to the test environment.