Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Drummer's avatar

How to create a test for a pivot table?

I want to create a test for the controller. There are three tables, Roles, Categories and Categories_roles, the connection is many to many.

Controller:

/**
 * Update connections.
 *
 * @return \Illuminate\Contracts\Support\Renderable
 */
public function update(Request $request) {

    $input = $request->get('category', []);
    foreach (Category::all() as $category) {
        $category->roles()->sync(Arr::get($input, $category->id, []));
    }
    return view('home');
}

I can not figure out how to write a test, there is a view in my head but I don't know how to implement. How I started to do.

Test:

/** @test */
public function test_admin_user_can_edit_categories_roles()
{
    $this->actingAs(\App\Models\User::factory()->create(['role_id' => 1]));
    $input = [
        "1" => [
            "1" => "1"
        ],
        "2" => [
            "1" => "1"
       ],
    ];
    $this->post('/admin/connections', $input);
}
0 likes
1 reply
fylzero's avatar

@drummer I don't believe actingAs will help you over an API (I could be wrong). This is how I've generally done this.

/** @test */
public function test_admin_user_can_edit_categories_roles()
{
    $user = User::factory()->create(['role_id' => 1]);

	// However you do this.
	// I typically like putting this method on the User model to make things easy.
	$apiToken = $user->generateApiToken();

    $data = [
        '1' => ['1' => '1'],
        '2' => ['1' => '1'],
    ];

    $response = $this->withHeaders(['Authorization' => $apiToken])
                     ->postJson('/admin/connections', $data);

 	$response->assertCreated();
}

Reading through the Laravel docs more you could also maybe try just adding the guard to your actingAs call: $this->actingAs($user, 'api')

Documented at the bottom of this section: https://laravel.com/docs/8.x/http-tests#session-and-authentication

1 like

Please or to participate in this conversation.