Laravel`assertSee`是否失败,因为时间戳是向后的?

时间:2019-09-02 10:45:58

标签: laravel

我进行了功能测试,检查是否向用户返回了正确数量的新闻文章。

预期的输出是按降序返回10篇文章。

Feature Test:

    public function a_user_can_view_news_articles()
    {
        $articles = factory(NewsArticle::class, 50)->create();
        $user = factory(User::class)->create();

        $this->actingAs($user)
            ->get('/api/news-articles')
            ->assertStatus(200)
            ->assertJsonCount(10)
            ->assertSee($articles->sortByDesc('created_at')->take(10));
    }

Route:

Route::get('/news-articles', function ()
{
    $articles = NewsArticle::orderBy('created_at', 'desc')->get()->take(10);
    return response()->json($articles);
});

但是测试失败,因为其中不包含相同的内容,并且如下所示,唯一的区别是数组中的时间戳记位置反转了。我不知道为什么会这样,我也不知道如何解决它。

alt

希望有人可以提供帮助!

1 个答案:

答案 0 :(得分:1)

在测试中时间戳是向后的,因为Eloquent的{​​{3}}的create函数存储了在模型工厂中定义的属性之前属性(例如idcreated_atupdated_at)并按该顺序返回它们
因此假设NewsArticleFactory

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\NewsArticle;
use Faker\Generator as Faker;

$factory->define(NewsArticle::class, function (Faker $faker) {
    return [
        'image' => $faker->imageUrl(),
        'content' => $faker->text,
    ];
});

FactoryBuilder

public function create(array $attributes = [])
{
    $results = $this->make($attributes); // Only 'image` and 'content'
    if ($results instanceof Model) {
            $this->store(collect([$results]));

            $this->callAfterCreating(collect([$results]));
    } else {
            $this->store($results);
            // Other columns in the database table are inserted AFTER
            dump($results); // 'image', 'content', 'updated_at', 'created_at', 'id'

            $this->callAfterCreating($results);
    }
    return $results;
}

然后调用factory(NewsArticle::class)->create(); ....
这就是我们得到的:

=> App\NewsArticle {#3143
     image: "https://lorempixel.com/640/480/?66495",
     content: "Est minima eveniet est nulla adipisci ut eos. Cupiditate beatae porro corporis ut aut reprehenderit esse. Vel debitis cumque dicta cum maxime. Quis iusto et ducimus voluptatem laboriosam rem.",
     updated_at: "2019-09-02 13:53:26",
     created_at: "2019-09-02 13:53:26",
     id: 351,
   }

但是Eloquent返回的列按照您的迁移中的定义正确排序,从而导致不匹配。
因此,一种解决方案是在id中手动添加自动递增的created_atupdated_atModel Factory时间戳,如下所示:

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\NewsArticle;
use Faker\Generator as Faker;
$autoIncrement = autoIncrement();

$factory->define(NewsArticle::class, function (Faker $faker) use ($autoIncrement) {
    $autoIncrement->next();
    return [
        'id' => $autoIncrement->current(),
        'image' => $faker->imageUrl(),
        'content' => $faker->text,
        'created_at' => now(),
        'updated_at' => now(),
    ];
});

function autoIncrement()
{
    $last_id = optional(NewsArticle::latest()->first())->id ?? 0;
    for ($i = $last_id; $i < 50; $i++) {
        yield $i;
    }
}

现在工厂电话会返回正确的订单

>>> factory(App\NewsArticle::class)->create();
=> App\NewsArticle {#3143
     id: 1,
     image: "https://lorempixel.com/640/480/?70536",
     content: "Nesciunt quibusdam architecto suscipit sint. Aut quaerat qui dolores ut dolores alias inventore eveniet. Voluptatem sed voluptatibus quo.",
     created_at: "2019-09-02 14:00:13",
     updated_at: "2019-09-02 14:00:13",
   }

希望这会有所帮助