Ad

Problem With Testing Method With ActingAs

- 1 answer

I have this code:

/**  @test */
public function testBasicExample()
{
    $user = User::find(1);
    // $user = factory(User::class)->create();
    $response = $this->actingAs(User::find(1))->json('POST', '/store/ad', [
                'title' => 'Hello World',
                'city' => 1,
                'phone' => '666555555',
                'description' => 'fasd asd as d asd as d asd as d asd as d asd as d asd as da sd asd',
                'user_id' => 1
    ]);

    $response
        ->assertStatus(201)
        ->assertJson([
            'created' => true,
        ]);
}

Unfortunatly at this moment I have a first problem. It couldn't see users table.

Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such table: users (SQL: select * from "users" where "users"."id" = 1 limit 1)

I'm looking how I can solve my problem and I found that I must using DatabaseMigrations. So I add that

use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends TestCase
{
    use DatabaseMigrations;
//...
}

But now I have new problem.

TypeError: Argument 1 passed to Illuminate\Foundation\Testing\TestCase::actingAs() must implement interface Illuminate\Contracts\Auth\Authenticatable, null given

So I implement that

use Illuminate\Contracts\Auth\Authenticatable;
class ExampleTest extends TestCase
{
    use DatabaseMigrations;
    use Authenticatable;
//...
}

It's generated new error:

Tests\Feature\ExampleTest cannot use Illuminate\Contracts\Auth\Authenticatable - it is not a trait

How can I solve my problem? How can I testing that?

@Edit

I found problem but I don't know why it doesn't work. I have this rule to valdiate city

'city' => 'required|integer|exists:cities,id'

Problem is the last rule: exists:cities,id. I tryed different id exist cities and nothing work.

Ad

Answer

The problem is that the DatabaseMigrations trait will reset the database after each test, so there is no user in the database when the test is run.

That means that you are currently passing null in the following line:

$this->actingAs(User::find(1))

You have to create a user first using the factory helper:

$user = factory(User::class)->create();

The following should solve your problem:

1 - Remove the following:

use Authenticatable;

Not sure why you even added this, the exception clearly states that the argument passed to $this->actingAs() has to implement the Authenticatable interface and not the current class.

2 - Change your test to something like this:

/**  @test */
public function testBasicExample()
{
    $this->actingAs(factory(User::class)->create())
        ->json('POST', '/store/ad', [
            'title' => 'Hello World',
            'city' => 1,
            'phone' => '666555555',
            'description' => 'fasd asd as d asd as d asd as d asd as d asd as d asd as da sd asd',
            'user_id' => 1
        ])
        ->assertStatus(201)
        ->assertJson(['created' => true]);
}
Ad
source: stackoverflow.com
Ad