我目前正在学习如何使用laravel应用程序编写PHPUnit测试,现在已经碰壁了几天。我的测试是,如果用户的ID与书籍的用户ID相同,则仅允许经过身份验证的用户更新书籍记录。
public function test_onlyAuthenticatedUserCanUpdateBookSuccessfully()
{
$user = factory(User::class)->create();
Passport::actingAs($user);
$book = factory(Book::class)->create();
dd($user, $book);
// $response = $this->json('PUT', '/api/books/'.$book->id, [
// 'id' => $book->id,
// 'title' => 'Updated book title',
// 'author'=> 'New Guy'
// ]);
// $response->assertStatus(201);
}
但是当我在进行故障排除时最初出现了403错误,我从转储的数据中注意到,创建的用户ID与书籍的user_id不同。
// Newly created user
#original: array:7 [
"name" => "Prof. Norwood Erdman"
"email" => "ihoeger@example.com"
"updated_at" => "2018-10-03 14:11:20"
"created_at" => "2018-10-03 14:11:20"
"id" => 2
]
// Newly created book
#attributes: array:6 [
"title" => "Quasi laudantium enim quas omnis."
"author" => "Mr. Jayson Roob"
"user_id" => 1
"updated_at" => "2018-10-03 14:11:20"
"created_at" => "2018-10-03 14:11:20"
"id" => 3
]
在我的代码中,我发现每次创建一本书时,由于我的BooksFactory使用的是user_id = 1
的硬编码值,因此user_id将设置为1。
$factory->define(Book::class, function (Faker $faker) {
return [
'title' => $faker->sentence,
'author' => $faker->name,
'user_id' => 1
];
});
如何编写代码,以便在创建图书的测试中,将经过身份验证的用户ID分配为图书的用户ID?我认为这将解决测试。我正在使用sqlite内存数据库进行测试,而不是mysql。
答案 0 :(得分:1)
您可以通过将具有要覆盖的属性和值的数组传递给create()
方法来覆盖工厂中的属性:
$book = factory(Book::class)->create(['user_id' => $user->id]);
此外,在工厂本身中创建创建用户可能是一个好主意,即:
$factory->define(Book::class, function (Faker $faker) {
return [
'title' => $faker->sentence,
'author' => $faker->name,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
];
});
如果要传递自己的ID,闭包中的user_id
值的原因是阻止创建另一个用户。
答案 1 :(得分:1)
作为一个小更新,对于 Laravel 8,语法将是:
$factory->define(Book::class, function (Faker $faker) {
return [
'title' => $faker->sentence,
'author' => $faker->name,
'user_id' => User::factory()->create()->id
];
});