I am new for laravel model unit testing.so please look and suggest me what i am doing wrong.my code is given below.I have 2 models User and UserState.
Model User
public function state()
{
return $this->hasOne('UserState');
}
Model UserState
public function user()
{
return $this->belongsTo('User');
}
now i am writing unit test for UserState. which is given below :
UnitTest UserStateModelTest
public function testUserRelationIsTrue(){
$user = new User();
$user->username = 'testusername';
$user->save();
$this->assertEquals($user->user_id, $user->state->id);
}
during test run by phpunit it generate error
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation:
1452 Cannot add or update a child row: a foreign key constraint fails
If you really want to test a relationship method, you can do it without even saving a model to the database. You still need to use the RefreshDatabase trait (or the DatabaseMigrations trait) or else the models won't be mapped to any table.
# tests/Unit/ParentTest.php
/**
* Test Parent has HasMany relationship with Child model
* @test
*/
public function has_many_children_with_parent_id_fk()
{
$parent = new Parent;
$foreign_key = 'parent_id';
// Get the relationship object, not the data collection
$relationship = $parent->children();
$related_model = $relationship->getRelated();
// Assert this is a HasMany relationship
$this->assertInstanceOf(HasMany::class, $relationship);
// Assert the related model is Child
$this->assertInstanceOf(Child::class, $related_model);
// Assert the foreign key is the one we specified
// (This can be useful if you do not use the default one)
$this->assertEquals($foreign_key, $relationship->getForeignKeyName());
// Assert the foreign key is a column
// of the database table mapped by the Child model
$this->assertTrue(Schema::hasColumns($related_model->getTable(), array($foreign_key)));
}
# tests/Unit/ChildTest.php
/**
* Test Child has belongsTo relationship with Parent model
* @test
*/
public function belongs_to_parent_with_parent_id_fk()
{
$child = new Child;
$foreign_key = 'parent_id';
// Get the relationship object, not the data collection
$relationship = $child->parent();
$related_model = $relationship->getRelated();
// Assert this is a BelongsTo relationship
$this->assertInstanceOf(BelongsTo::class, $relationship);
// Assert the related model is Parent
$this->assertInstanceOf(Parent::class, $related_model);
// Assert the foreign key is the one we specified
// (This can be useful if you do not use the default one)
$this->assertEquals($foreign_key, $relationship->getForeignKeyName());
// Assert the foreign key is a column
// of the database table mapped by the Child model
$this->assertTrue(Schema::hasColumns($relationship->getParent()->getTable(), array($foreign_key)));
}
This is a bit of a handful but you can make a custom assertion to encapsulate all of this in the TestCase all tests files extend. The following methods suited my needs
# tests/TestCase.php
public function assertHasManyUsing($related_model, $relationship, $foreign_key)
{
$this->assertInstanceOf(HasMany::class, $relationship);
$this->assertInstanceOf($related_model, $relationship->getRelated());
$this->assertEquals($foreign_key, $relationship->getForeignKeyName());
$this->assertTrue(Schema::hasColumns($relationship->getRelated()->getTable(), array($foreign_key)));
}
public function assertBelongsToUsing($related_model, $relationship, $foreign_key)
{
$this->assertInstanceOf(BelongsTo::class, $relationship);
$this->assertInstanceOf($related_model, $relationship->getRelated());
$this->assertEquals($foreign_key, $relationship->getForeignKeyName());
$this->assertTrue(Schema::hasColumns($relationship->getParent()->getTable(), array($foreign_key)));
}
And now, refactoring the tests look like this
# tests/Unit/ParentTest.php
/**
* Test Parent has HasMany relationship with Child model
* @test
*/
public function has_many_children_with_parent_id_fk()
{
$parent = new Parent;
$this->assertHasManyUsing(Child::class, $parent->children(), 'parent_id');
}
# tests/Unit/ChildTest.php
/**
* Test Child has belongsTo relationship with Parent model
* @test
*/
public function belongs_to_parent_with_parent_id_fk()
{
$child = new Child;
$this->assertBelongsToUsing(Parent::class, $child->parent(), 'parent_id');
}
Argument #1 of PHPUnit\Framework\Assert::assertInstanceOf() must be a class or interface name
tests\TestCase.php:14
> 10▕ use CreatesApplication;
> 11▕
> 12▕ public function assertHasManyUsing($related_model, $relationship, $foreign_key)
> 13▕ {
> ➜ 14▕ $this->assertInstanceOf(HasMany::class, $relationship);
> 15▕ $this->assertInstanceOf($related_model, $relationship->getRelated());
> 16▕ $this->assertEquals($foreign_key, $relationship->getForeignKeyName());
> 17▕ $this->assertTrue(Schema::hasColumns($relationship->getRelated()->getTable(),
> array($foreign_key)));
> 18▕ }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With