'Laravel phpunit test failing authorization
I have a working api
only application.
I am required to write a test decided to use laravel
's phpunit test. This simple app allows only authenticated users can store
, update
or delete
a book
. Everyone else (authenticated or not) can retrieve a list of all books
or view details of one book
.
For my books
test, I have written a test that first creates a user
then a random token
for the user. Then the token is passed using withHeaders
when posting a new book record
class BooksTest extends TestCase
{
public function test_onlyAuthenticatedUserCanAddBookSuccessfully()
{
$user = factory(User::class)->create();
$token = str_random(10);
$book = factory(Book::class)->create();
$response = $this->withHeaders(['Authorization' => "Bearer $token"])
->json('POST', '/api/books', [
'title' => 'book post',
'author' => 'post author'
]);
$response->assertStatus(201);
}
}
Here I am using the default Laravel 5.6 UserFactory
and my own BookFactory
$factory->define(Book::class, function (Faker $faker) {
return [
'title' => $faker->sentence,
'author' => $faker->name,
'user_id' => 1
];
});
$factory->define(Rating::class, function (Faker $faker) {
return [
'user_id' => 1,
'book_id' => mt_rand(1, 2),
'rating' => mt_rand(1, 5)
];
});
When I run the test, it fails and I get 401
instead of 200
which means the user is unauthorized.
I have a feeling that I have probably not set the $user
in my test properly to be used during POST
but I am not sure and really need help to get it right.
Solution 1:[1]
you can send headers in the fourth params of json() method as
$response = $this->json('POST', '/api/books', [
'title' => 'book post',
'author' => 'post author'
],['Authorization' => "Bearer $token"]);
since json method itself has provision to pass headers
or you can use post() method as
$response = $this->post('/api/books', [
'title' => 'book post',
'author' => 'post author'
],['Authorization' => "Bearer $token"]);
Try this instead hope this solves your issues
Solution 2:[2]
Not sure how authentication is hooked on your application, but you could try this:
...
$this->actingAs($user)
->jsonPost('/api/books', [
// ...
]);
$response->assertStatus(201);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jayashree |
Solution 2 | Michael Grove |