我进行了功能测试,检查是否向用户返回了正确数量的新闻文章。
预期的输出是按降序返回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);
});
但是测试失败,因为其中不包含相同的内容,并且如下所示,唯一的区别是数组中的时间戳记位置反转了。我不知道为什么会这样,我也不知道如何解决它。
希望有人可以提供帮助!
答案 0 :(得分:1)
在测试中时间戳是向后的,因为Eloquent
的{{3}}的create
函数存储了在模型工厂中定义的属性之前属性(例如id
,created_at
,updated_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,
];
});
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_at
,updated_at
和Model 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",
}
希望这会有所帮助