自Laravel 5.6起,Eloquent Date Casting可用。
所以我有一个模型 MyModel :
class MyModel extends Model {
protected $casts = ['from' => 'date:Y-m-d', 'to' => 'date:Y-m-d'];
protected $dates = ['from', 'to'];
}
还有工厂:
$factory->define(MyModel::class, function(Faker $faker) {
return [
'from' => Carbon::instance($faker->dateTime),
'to' => Carbon::instance($faker->dateTime),
// some more attributes
];
}
在单元测试中,我正在寻找 MyModel 的实例:
/** @test */
public function example() {
$myModel = factory(MyModel::class)->create();
$this->assertDatabaseHas('my_models', $myModel->attributesToArray());
}
这就是我得到的(摘录):
无法断言表[my_models]中的行与属性{
“来自”:“ 2019-01-12”,
“至”:“ 2019-02-13”,
}。
找到:[{
“ from”:“ 2019-01-12 00:00:00”,
“至”:“ 2019-02-13 00:00:00”,
}]。
显然,测试失败了,因为时间被附加在数据库记录的字段中。它们的类型为date
。
我可以将断言更新为这样的内容...
$this->assertDatabaseHas('my_models', [
'from' => $myModel->from->toDateTimeString(),
'to' => $myModel->to->toDateTimeString(),
] + $myModel->attributesToArray());
...但是那离优雅很远。
我该怎么做才能使此断言成功?
答案 0 :(得分:1)
我最终写了一个新的断言方法,该方法将模型的日期属性格式化为Y-m-d H:i:s
以进行正确的比较:
protected function assertDatabaseHasModel(string $table, Model $model, ?string $connection = null) {
$attributes = $model->attributesToArray();
$reflection = new ReflectionClass($model);
$property = $reflection->getProperty('casts');
$property->setAccessible(true);
collect($property->getValue($model))
->filter(function(string $cast) {
return starts_with($cast, 'date:');
})
->each(function(string $cast, string $field) use($model, &$attributes) {
$attributes[$field] = $model->$field->toDateTimeString();
});
$this->assertDatabaseHas($table, $attributes, $connection);
}