You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel9单元测试断言200失败,返回302重定向问题排查

Laravel路由单元测试:正确测试返回back()重定向的场景

测试用例test_client_save_access_if_authorised执行时,assertStatus(200)断言失败,实际返回302状态码。确认控制器逻辑已正常执行且数据保存成功,问题源于控制器返回back()生成重定向响应,以下是正确的测试方案:

原测试代码

public function test_client_save_access_if_authorised()
{
    $this->seed(TestSeederBase::class);
    $user = User::find(1);

    $response = $this->actingAs($user, 'web')
        ->withSession(['banned' => false])
        ->post('/client/save', [
            'csrf_token' => csrf_token(),
            'id' => 1,
            'title' => 'Test Title',
            'contact_1_title' => 'Another Title',
            'contact_1_email' => 'cas@example.com',
            'contact_1_phone_number' => '01234567890',
        ]);

    $response->dumpHeaders();
    $response->dumpSession();
    $response->dump();

    $response->assertStatus(200);

    $task = JobWorkItem::where('job_number', 1)
        ->where('user_id', 1)
        ->first();

    $this->assertSame(1, $task->job_number);
}

对应控制器代码

/**
 * @param ClientRequest $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store( ClientRequest $request )
{
    $is_enabled = 0;
    if (isset($request->is_enabled) && $request->is_enabled === 'on') {
        $is_enabled = 1;
    }

    $client = Client::find($request->id);
    $client->is_enabled = $is_enabled;
    $client->title = $request->title;
    $client->save();

    // 更新联系人数据
    $all = ClientContact::where('client_id', $request->id)->get();
    foreach ($all as $cc) {
        if (isset($request->{'contact_' . $cc->id . '_title'})) {
            $title = $request->{'contact_' . $cc->id . '_title'};
            $email = $request->{'contact_' . $cc->id . '_email'};
            $phone = $request->{'contact_' . $cc->id . '_phone_number'};
            if ($title === '-' || $title === '') {
                $cc->forceDelete();
            } else {
                $cc->title = $title;
                $cc->email = $email;
                $cc->phone_number = $phone;
                $cc->save();
            }
        }
    }

    return back();
}

问题核心

控制器返回的back()会生成302重定向响应,而非200状态码的页面响应,因此原断言assertStatus(200)必然失败。同时back()依赖请求的HTTP_REFERER头,测试环境中若未设置,Laravel会默认重定向到APP_URL对应的地址。

正确测试方案

1. 调整响应断言逻辑

将状态码断言改为验证重定向,同时可指定重定向目标:

  • 用assertStatus(302)验证重定向状态码
  • 用assertRedirectBack()或assertRedirect($url)验证重定向目标

2. 强化业务逻辑验证

测试的核心是确认数据是否正确更新,而非仅验证响应状态。

3. 移除冗余参数

Laravel测试框架会自动处理CSRF令牌,无需手动在请求中传入csrf_token()参数。

修改后的测试代码示例

public function test_client_save_access_if_authorised()
{
    $this->seed(TestSeederBase::class);
    $user = User::find(1);

    // 设置referer头,模拟从编辑页面发起请求
    $response = $this->actingAs($user, 'web')
        ->withSession(['banned' => false])
        ->withHeaders(['HTTP_REFERER' => '/client/edit/1'])
        ->post('/client/save', [
            'id' => 1,
            'title' => 'Test Title',
            'contact_1_title' => 'Another Title',
            'contact_1_email' => 'cas@example.com',
            'contact_1_phone_number' => '01234567890',
        ]);

    // 断言重定向状态码
    $response->assertStatus(302);
    // 断言重定向到指定来源地址
    $response->assertRedirect('/client/edit/1');
    // 或使用专门的back()断言方法
    // $response->assertRedirectBack();

    // 验证客户端数据更新
    $client = Client::find(1);
    $this->assertEquals('Test Title', $client->title);
    $this->assertEquals(0, $client->is_enabled);

    // 验证联系人数据更新
    $contact = ClientContact::find(1);
    $this->assertEquals('Another Title', $contact->title);
    $this->assertEquals('cas@example.com', $contact->email);
    $this->assertEquals('01234567890', $contact->phone_number);

    // 保留原有JobWorkItem相关断言(若与测试逻辑相关)
    $task = JobWorkItem::where('job_number', 1)
        ->where('user_id', 1)
        ->first();
    $this->assertNotNull($task);
    $this->assertSame(1, $task->job_number);
}

内容的提问来源于stack exchange,提问作者ThurstonLevi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:05:28