简体   繁体   中英

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.

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

Not sure how authentication is hooked on your application, but you could try this:

...

$this->actingAs($user)
    ->jsonPost('/api/books', [
        // ...  
    ]);

$response->assertStatus(201);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM