Laravel/PHPUnit:断言两个模型的相同性



当在Laravel中进行集成测试(使用数据库(时。断言同一 Eloquent 模型的两个实例相同的最佳方法是什么?

断言等于$model $model

简单地使用->assertEquals($modelOne, $modelTwo);是行不通的,即使它们是相同的 PHPUnit 检查类属性,例如wasRecentlyCreated有时模型id可以是字符串或整数。

断言等于$model->id $model->id

这里的问题是模型一可能是另一个模型的实例,例如:

AssertEquals(Person::find(1)->id, Animal::find(1)->id);返回 true。

断言等于$model->toArray() $model->toArray()

这里的问题是属性并不总是转换为相同的类型,我不是 100% 确定为什么,但有时模型属性会是一个int,有时是一个数字string

AssertEquals($address->toArray(), $user->address->toArray())

[ postcode => 2454 ]
[ postcode => "2454" ]

如何以简单、干净和可重复的方式断言两个 Eloquent 模型是相同的数据库记录?

一种选择是在IlluminateDatabaseEloquent类上使用PHPUnit的assertTrue方法与is方法结合使用。

$this->assertTrue($modelOne->is($modelTwo));

如果作为参数传递的模型不是null,则is方法将返回 true,具有相同的主键、相同的表和相同的连接。

关于测试属性的相同性,您只需对每个模型的属性使用 PHPUnit 的assertEquals应该是安全的,您可以使用 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());

在我的测试中,我发现这些断言通过了。assertEquals 方法松散地比较值,因为值被比较为使用 == 而不是严格的比较(或恒等(运算符 === 。在内部,它将对提供的两个数组进行排序,并松散地比较具有相同键的值。如果一个模型上有任何额外的属性,而另一个模型没有,则断言也将失败。