Laravel测试中如何同时断言对象修改成功与无会话错误?
Laravel测试:解决断言冲突的优雅方案
在Laravel功能测试里,你遇到的这个问题可以通过两种更优雅的方式解决,无需修改前端添加data-errors属性:
方案一:拆分测试用例(推荐)
遵循测试的单一职责原则,把两个验证点拆成独立测试,互不干扰:
测试1:验证对象修改成功后页面显示正确内容
/** @test */ public function updates_object_and_displays_new_value() { $object = // 提前创建测试用的模型实例 $newValue = 'New value'; $this->patch(route('objects.update', $object), [ 'field_name' => $newValue, // 替换为你的实际字段名 ])->followingRedirects(); $this->assertSee($newValue); }
测试2:验证更新操作无会话错误
/** @test */ public function no_session_errors_on_successful_update() { $object = // 创建相同的测试模型实例 $newValue = 'New value'; $response = $this->patch(route('objects.update', $object), [ 'field_name' => $newValue, ]); $response->assertSessionDoesntHaveErrors(); // 可选:额外验证跳转地址是否符合预期 $response->assertRedirect(route('objects.show', $object)); }
拆分后每个测试只专注一个逻辑点,代码更清晰,也彻底避免了followingRedirects()清除会话的问题。
方案二:同一测试中分步处理
如果一定要在单个测试里完成两个断言,可以先发送请求不跟进跳转,验证会话后再手动访问跳转页面:
/** @test */ public function updates_object_correctly_without_errors() { $object = // 创建测试模型实例 $newValue = 'New value'; // 第一步:发送更新请求,不跟进跳转 $response = $this->patch(route('objects.update', $object), [ 'field_name' => $newValue, ]); // 先断言会话无错误 $response->assertSessionDoesntHaveErrors(); // 获取跳转的目标URL $redirectUrl = $response->headers->get('Location'); // 第二步:访问跳转后的页面,验证内容 $this->get($redirectUrl)->assertSee($newValue); }
这种方式完全在测试层面解决问题,无需改动任何前端代码,比添加data-errors属性更符合Laravel测试的最佳实践。
内容的提问来源于stack exchange,提问作者Chuck Le Butt
相关产品推荐
相关产品推荐

