When integration testing (using a database) in Laravel. What is the best way to assert that two instances of the same Eloquent model are the same?
AssertEquals $model $model
Simply using ->assertEquals($modelOne, $modelTwo);
wont work as even if they are the same PHPUnit checks class properties such as wasRecentlyCreated
and sometimes model id
s can be a string or an integer.
AssertEquals $model->id $model->id
The problem here is model one may be an instance of another model e.g:
AssertEquals(Person::find(1)->id, Animal::find(1)->id);
returns true.
AssertEquals $model->toArray() $model->toArray()
The issue here is properties are not always cast as the same type, Im not 100% sure why but there are times a models properties will be an int
and other times a number string
AssertEquals($address->toArray(), $user->address->toArray())
[ postcode => 2454 ] [ postcode => "2454" ]
How to assert in a simple, clean and repeatable manner two Eloquent models are the same database record?
Advertisement
Answer
One option would be to use PHPUnit’s assertTrue
method combined with the is
method on the IlluminateDatabaseEloquent
class.
$this->assertTrue($modelOne->is($modelTwo));
The is
method will return true if the model you pass as an argument is not null
, has the same primary key, same table and same connection.
With regards to testing the sameness of attributes, you should be safe just using PHPUnit’s assertEquals
on each model’s attributes, which you can retrieve using getAttributes
.
$model1 = new Model(['id' => 1, 'name' => 'test', 'enabled' => 0, 'number' => '1']); $model2 = new Model(['id' => 1, 'name' => 'test', 'enabled' => false, 'number' => 1]); $this->assertEquals($model1->getAttributes(), $model2->getAttributes());
In my tests, I have found that these assertions pass. The assertEquals
method compares values loosely, in that values are compared as using ==
rather than the strict comparison (or identity) operator, ===
. Internally, it will sort both of the arrays provided, and loosely compare values with the same keys. If you have any extra attributes on one model but not the other, the assertion will fail as well.