Unable to testing Many to Many Relationship Assertion Failed :
Failed asserting that Illuminate\Database\Eloquent\Collection Object (...) is an instance of class "App\Tag".
UnitThreadTest.php
namespace Tests\Unit;
use App\Tag;
use App\Thread;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ThreadTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function it_belongs_to_many_tags()
{
$thread = factory(Thread::class)->create();
$this->assertInstanceOf(Tag::class, $thread->tags);
}
}
2019_06_01_114457_create_threads_table.php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateThreadsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('threads', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('threads');
}
}
2019_06_01_114508_create_tags_table.php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tags');
}
}
pivot table (2019_06_01_114720_create_tag_thread_table.php)
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagThreadTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tag_thread', function (Blueprint $table) {
$table->primary(['tag_id','thread_id']);
$table->unsignedBigInteger('tag_id');
$table->unsignedBigInteger('thread_id');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->foreign('thread_id')->references('id')->on('threads')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tag_thread');
}
}
Thread.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Thread extends Model
{
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
Tag.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
public function threads()
{
return $this->belongsToMany(Tag::class);
}
}
ThreadFactory.php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Thread;
use Faker\Generator as Faker;
$factory->define(Thread::class, function (Faker $faker) {
return [
'title' => $faker->sentence,
'body' => $faker->paragraph
];
});
TagFactory.php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Thread;
use Faker\Generator as Faker;
$factory->define(Thread::class, function (Faker $faker) {
return [
'name' => $faker->word
];
});
Note that the code alone will work but its test not.
Your test is incorrect. $thread->tags returns a collection of tags, not a single tag.
You can do something like this:
$this->assertInstanceOf(Tag::class, $thread->tags[0]);
@staudenmeir now:
ErrorException : Undefined offset: 0
Your test doesn't create any tags, so the relationship result is empty.
I dont think so that was the problem , with Tag factory :
public function it_belongs_to_many_tags()
{
factory(Tag::class)->create();
$thread = factory(Thread::class)->create();
$this->assertInstanceOf(Tag::class, $thread->tags[0]);
}
same error:
ErrorException : Undefined offset: 0
You also have to create records in the pivot table, that's what the relationship is all about.
thanks i forgot about the pivot table, here is the solution maybe helps somebody :
public function it_belongs_to_many_tags()
{
$tag = factory(Tag::class)->create();
$thread = factory(Thread::class)->create();
DB::table('tag_thread')->insert([
'tag_id' => $tag->id,
'thread_id' => $thread->id
]);
$this->assertInstanceOf(Tag::class, $thread->tags[0]);
}
Most helpful comment
You also have to create records in the pivot table, that's what the relationship is all about.