I just finished the "PHP Testing Jargon" course, and I'm creating a simple to-do list practice app to get TDD under my belt.
The app structure will look like this: the user can create projects, the project can have lists, and the lists have items. This involves SQL foreign key constraints creating relationships between the lists and projects that their children belong too.
So obviously you must first create a project before you can create anything else. I want to create the functionality that creates a new project in the database proper TDD style. The problem is I have no idea what I'm doing. Here is my Project model and my newProjectTest:
Project.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class Project extends Model
{
use HasFactory;
public static function create($name)
{
$newProject = new Project;
$newProject->name = $name;
// $newProject->user_id = Auth::id();
$newProject->user_id = 123; // Don't know how to fake a user ID in a test
$newProject->save();
}
}
newProjectTest.php
<?php
namespace Tests\Unit;
use App\Models\Project;
use Tests\TestCase;
class newProjectTest extends TestCase
{
/**
* @return void
*/
public function test_it_creates_a_new_project ()
{
$newProject = Project::create('Project 1');
$this->assertNotNull($newProject);
}
}
And the migration if it helps:
..._create_projects_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('name');
$table->boolean('completed')->default(false);
$table->timestamps();
// One-to-many on projects table
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('projects');
}
};
When I run the test, I get : Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (to_do_ninja.projects, CONSTRAINT projects_user_id_foreign FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE)
I'm super confused at this point. I'm sure there are 1,000 things I'm doing wrong, I apologize in advance lol. I'm trying to learn. While this is all new to me, I'm hoping this is something trivial for an experienced TDD developer. Any help is very much appreciated.