php - 在数据库中搜索模型时,由于日期时间格式测试失败
问题描述
从 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] 中的行与属性 {
“from”:“2019-01-12”、
“to”:“2019-02-13”、
} 匹配。
找到:[{
“from”:“2019-01-12 00:00:00”,
“to”:“2019-02-13 00:00:00”,
}]。
显然测试失败了,因为时间附加在数据库记录的字段中。它们是类型date
。
我可以将断言更新为这样的东西......
$this->assertDatabaseHas('my_models', [
'from' => $myModel->from->toDateTimeString(),
'to' => $myModel->to->toDateTimeString(),
] + $myModel->attributesToArray());
...但这远非优雅。
我该怎么做才能使这个断言成功?
解决方案
我最终编写了一个新的断言方法,该方法将模型的日期属性格式化Y-m-d H:i:s
为正确比较:
protected function assertDatabaseHasModel(string $table, Model $model, ?string $connection = null): void
{
$attributes = $model->attributesToArray();
$reflection = new ReflectionClass($model);
$property = $reflection->getProperty('casts');
$property->setAccessible(true);
collect($property->getValue($model))->each(function (string $cast, string $field) use ($model, &$attributes) {
if (Str::startsWith($cast, 'date:')) {
$attributes[$field] = $model->$field->toDateTimeString();
} elseif (in_array($cast, ['array', 'object'], true) && $model->$field !== null) {
$attributes[$field] = $this->castAsJson($model->$field);
}
});
$this->assertDatabaseHas($table, $attributes, $connection);
}
推荐阅读
- javascript - 正则表达式提取特定模式的段落
- swift - Swift4 - Xcode 9 PCH 错误
- c++ - 使用 BOOST property_tree / iostreams / filesystem / foreach - 导致链接错误
- javascript - JavaScript 承诺初学者
- php - 如何在 JSON 中打印 max() 值
- ruby-on-rails - ActiveStorage Rails 5.2.0 的默认值
- spring-boot - 带有客户端连接工厂的入站适配器上的 client-mode="true" 和 retryInterval
- google-cloud-vision - 如何使用 Google Vision API 检测剪掉的头部?
- c# - 在c#中上传图片
- reactjs - React Webpack 4 解决别名