php - 在数据库中搜索模型时,由于日期时间格式,测试失败

标签 php laravel phpunit

从 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());
}

这就是我得到的(摘录):

Failed asserting that a row in the table [my_models] matches the attributes {
"from": "2019-01-12",
"to": "2019-02-13",
}.
Found: [{
"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);
}

关于php - 在数据库中搜索模型时,由于日期时间格式,测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52853189/

相关文章:

javascript - Laravel jQuery AJAX 实时搜索

php - Laravel 5.0 Auth 使用 Homestead 而不是 .env DB

php - 使用字符串获取模型

laravel - 测试通知后数据库通知不显示

php - 检查 mock 的方法是否在没有传递任何参数的情况下被调用(在 phpunit 中)

phpunit - 如何强制 phpunit 失败

php - 结合 servlet 和 "normal"网络服务器

php - 拉维 4 : validation unique (database) multiple where clauses

java - 通过 URL 编码从 PHP 到 Java 的时间敏感的加密/解密错误

php - 查找两个相等值之间的数据