我在Laravel 5.7中进行了一项测试,该测试通过了90%的时间。
有时会失败,这是因为created_at和updated_at之间还有一秒:
在数据库中:
"created_at" => "2019-01-23 18:27:36"
"updated_at" => "2019-01-23 18:27:37"
在本地设置$ setting中:
"created_at" => "2019-01-23 18:27:36"
"updated_at" => "2019-01-23 18:27:36"
我的测试:
/** @test */
public function it_update_setting_for_championship()
{
$tournament = factory(Tournament::class)->create();
$championship = factory(Championship::class)->create(['tournament_id' => $tournament->id, 'category_id' => 2]);
$setting = factory(ChampionshipSettings::class)->create(['championship_id' => $championship->id]);
$this->call('PUT', '/championships/' . $championship->id . '/settings/' . $setting->id, $setting->toArray());
$this->assertResponseOk();
$this->seeInDatabase('championship_settings', $setting->toArray());
}
当然,我可以将$setting->toArray()
放入一个变量中,然后将unset
created_at
和updated_at
放入一个变量中,但是感觉不对...
为什么它不总是发生?
有人有更好的解决方案吗?
编辑:
ChampionshipSettingsFactory:
$factory->define(ChampionshipSettings::class, function (Faker\Generator $faker) use ($factory) {
$tcs = Championship::all()->pluck('id')->toArray();
return [
'championship_id' => $faker->randomElement($tcs),
'teamSize' => $faker->numberBetween(0, 6),
'fightingAreas' => $faker->numberBetween(0, 4),
'fightDuration' => "03:00",
'hasPreliminary' => $faker->boolean(),
'preliminaryWinner' => $faker->numberBetween(1, 2),
'hasEncho' => $faker->boolean(),
'enchoQty' => $faker->numberBetween(0, 4),
'enchoDuration' => "01:00",
'hasHantei' => $faker->boolean(),
'cost' => $faker->numberBetween(0, 100),
'preliminaryGroupSize' => $faker->numberBetween(0, 10),
'preliminaryDuration' => $faker->numberBetween(0, 10),
'seedQuantity' => $faker->numberBetween(0, 4),
'hanteiLimit' => $faker->numberBetween(0, 10), // 1/2 Finals
'enchoGoldPoint' => $faker->numberBetween(0, 10), // Step where Encho has no more time limit
'limitByEntity' => $faker->numberBetween(0, 10),
];
});
答案 0 :(得分:0)
您的问题是工厂的运作方式。您正在数据库中创建元素,然后在创建后覆盖值。
带有工厂的怪异的怪癖是,除非您在key => value
对中使用函数作为值,否则它们将始终运行工厂代码,然后套用您被覆盖的代码。
将您的出厂设置更改为以下内容,以便您将函数用作ID:
$factory->define(ChampionshipSettings::class, function (Faker\Generator $faker) {
return [
'championship_id' => function() {
// Setting the id to a function makes it so the below query doesn't run
// If we do an overwrite when we are using this factory.
return Championship::inRandomOrder()->first()->id
},
'teamSize' => $faker->numberBetween(0, 6),
'fightingAreas' => $faker->numberBetween(0, 4),
'fightDuration' => "03:00",
'hasPreliminary' => $faker->boolean(),
'preliminaryWinner' => $faker->numberBetween(1, 2),
'hasEncho' => $faker->boolean(),
'enchoQty' => $faker->numberBetween(0, 4),
'enchoDuration' => "01:00",
'hasHantei' => $faker->boolean(),
'cost' => $faker->numberBetween(0, 100),
'preliminaryGroupSize' => $faker->numberBetween(0, 10),
'preliminaryDuration' => $faker->numberBetween(0, 10),
'seedQuantity' => $faker->numberBetween(0, 4),
'hanteiLimit' => $faker->numberBetween(0, 10), // 1/2 Finals
'enchoGoldPoint' => $faker->numberBetween(0, 10), // Step where Encho has no more time limit
'limitByEntity' => $faker->numberBetween(0, 10),
];
});
到目前为止,当您运行时:
$setting = factory(ChampionshipSettings::class)->create([
'championship_id' => $championship->id
]);
即使您如上所述覆盖冠军ID,您也将不再运行查询以查找数据库来查找冠军ID。
此方法在https://laravel.com/docs/5.7/database-testing#relationships
的文档中提到了(几乎没有为什么)。让我知道问题是否仍然存在。