Laravel测试返回404错误:预期状态码[201等]却收到404
为什么Laravel测试会返回404?(预期是201/3xx状态码)
预期响应状态码应为[201, 301, 302, 303, 307, 308],但实际收到404错误,明明操作都正确,问题出在哪?
测试代码
public function test_user_can_add_product_to_cart() { $user = User::factory()->create(); $this->actingAs($user); $response = $this->post('addProductToCart', ['quantity' => 4], [ Product::first(), ]); $response->assertRedirect('/products'); }
路由定义
Route::middleware([auth::class])->group(function () { Route::post('/cart/add/{product}', [CartController::class, 'addProductToCart'])->name('addProductToCart'); }
控制器方法
public function addProductToCart(Request $request, Product $product) { return redirect()->route('products.index')->with('alert', 'Added product to cart'); }
问题原因及修复方案
1. 请求地址错误,路由参数传递方式完全错误
你的路由定义的是带参数的URL /cart/add/{product},并且命名为addProductToCart,但测试里直接post字符串'addProductToCart'——这既不是完整的路由URL,也没有正确使用命名路由的方式传递参数。
另外,你把Product::first()放到了post方法的第三个参数(请求头位置),这完全不符合方法参数规则,路由参数应该作为URL的一部分传递。
2. 未确保Product实例存在
测试中使用Product::first(),如果测试数据库里没有预先创建的Product,这个方法会返回null;就算有数据,这样传递参数的方式也不成立。
修复后的测试代码
public function test_user_can_add_product_to_cart() { // 提前创建测试用的用户和商品实例 $user = User::factory()->create(); $product = Product::factory()->create(); $this->actingAs($user); // 方式一:用命名路由生成带参数的URL $response = $this->post(route('addProductToCart', ['product' => $product->id]), ['quantity' => 4]); // 方式二:直接拼接完整的路由URL // $response = $this->post("/cart/add/{$product->id}", ['quantity' => 4]); $response->assertRedirect('/products'); }
关键注意点
- 调用路由时,要么用
route()函数生成带参数的命名路由URL,要么直接拼接包含参数的完整URL - 测试中必须预先创建依赖的模型实例(比如这里的Product),避免出现找不到资源的情况
- Laravel测试的
post方法参数顺序是:$uri, $data = [], $headers = [],不要把路由参数放到请求头的位置
内容的提问来源于stack exchange,提问作者Tilda Mendozae
相关产品推荐
相关产品推荐

