3

I am trying to write a PHPUnit test that authenticates a user first before allowing the user to make a post request but got the error

1) Tests\Feature\BooksTest::test_onlyAuthenticatedUserCanAddBookSuccessfully ErrorException: Trying to get property 'client' of non-object

C:\wamp64\www\bookstore\vendor\laravel\passport\src\ClientRepository.php:89 C:\wamp64\www\bookstore\vendor\laravel\passport\src\PersonalAccessTokenFactory.php:71 C:\wamp64\www\bookstore\vendor\laravel\passport\src\HasApiTokens.php:67 C:\wamp64\www\bookstore\tests\Feature\BooksTest.php:20

When I run my BooksTest

public function test_onlyAuthenticatedUserCanAddBookSuccessfully()
{
    $user = factory(User::class)->create();
    $token = $user->createToken('bookbook')->accessToken;

    $response = $this->withHeaders(['Authorization' => 'Bearer '.$token])
        ->json('POST', '/api/books', [
            'title' => 'new book post',
            'author' => 'new author',
            'user_id' => $user->id
        ]);

    $response->assertStatus(201);
}

It's my first time working with PHPUnit test, and I have no idea why I'm getting this error. How do I make it work?

1 Answer 1

5

You can use Passport::actingAs to accomplish this.

For example:

public function test_onlyAuthenticatedUserCanAddBookSuccessfully()
{
    $user = factory(User::class)->create();

    Passport::actingAs($user);

    $response = $this->json('POST', '/api/books', [
            'title' => 'new book post',
            'author' => 'new author',
            'user_id' => $user->id
        ]);

    $response->assertStatus(201);
}

See the documentation here - https://laravel.com/docs/5.7/passport#testing

Sign up to request clarification or add additional context in comments.

3 Comments

Got an error ErrorException: Undefined variable: user from the line where I am setting the user_id But if I hard code it, the test is passed. How can i use the id of the created user instead of hard coding a value?
Just assign the response from the factory to a variable. See my updated answer.
You're also can use $this->actingAs($user, 'api') to create authentication using passport. This solution only works if you're using Laravel Passport as default API Authentication.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.