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

Laravel中如何测试PATCH方法?实体更新测试未生效排查

解决Laravel中PATCH更新方法的测试问题

问题场景

在Laravel中测试Product实体的PATCH更新接口时,测试用例无报错通过,但数据库中的数据并未更新为传入的新值。测试流程为:通过工厂创建Product实例,以认证用户身份调用patch()方法传入更新数据,最后查询数据库发现数据仍为初始值。

测试代码

public function test_check_count_additional_photos()
{
    $product = Product::factory()->create();

    $this->actingAs($this->user)->patch(route('editProduct', ['id' => $this->user->id, 'product' => $product->id]), [
        'title' => 'Updated product',
        'description' => 'Updated Product description',
        'price' => 1000,
        'visible' => true,
    ]);

    dd(Product::all())
}

控制器代码

public function editProduct(int $userId, Product $product, UpdateProductRequest $request)
{
    $product->title = isset($request->title) ? $request->title :  $product->title;
    $product->description = isset($request->description) ? $request->description : $product->description;
    $product->price = isset($request->price)  ? $request->price : $product->price;
    $product->visible = isset($request->visible) ? 1 : 0;
    $product->user_id = $userId;
    $product->update();
}

排查与解决方案

1. 路由参数匹配校验

检查editProduct路由的定义,确保路由参数名与控制器方法参数对应。控制器方法接收的是$userId和$product,但测试中route()传入的参数是['id' => $this->user->id, 'product' => $product->id],如果路由定义的参数名是user而非id,会导致控制器拿到错误的用户ID,甚至匹配到错误的Product实例。

修改测试中的路由参数为与路由定义一致的名称,例如:

route('editProduct', ['user' => $this->user->id, 'product' => $product->id])

2. 请求验证规则检查

查看UpdateProductRequest的验证规则,确认title、description、price、visible等字段是否被允许通过,是否存在required或其他规则导致请求数据被过滤。若验证未通过,控制器不会执行更新逻辑,但测试可能未捕获到错误。

在测试中添加断言验证请求无错误:

$this->assertSessionHasNoErrors();

3. 控制器逻辑优化

  • 字段赋值逻辑问题:isset($request->title)无法正确识别空字符串等合法值,改用$request->input('字段名', 默认值)简化赋值,同时确保布尔值处理准确:
public function editProduct(int $userId, Product $product, UpdateProductRequest $request)
{
    $product->title = $request->input('title', $product->title);
    $product->description = $request->input('description', $product->description);
    $product->price = $request->input('price', $product->price);
    $product->visible = $request->boolean('visible');
    $product->user_id = $userId;
    $product->save();
}

或直接使用fill()批量赋值(需确保模型的$fillable属性包含这些字段):

$product->fill($request->only(['title', 'description', 'price', 'visible']))->save();
  • 模型权限校验:检查Product模型是否有全局作用域或策略限制,确保当前认证用户有权限更新该Product实例。

4. 测试用例规范优化

Laravel测试默认开启事务,测试结束后会回滚数据,使用dd()可能无法看到真实的更新结果。改用断言验证数据库数据:

public function test_check_count_additional_photos()
{
    $product = Product::factory()->create();

    $this->actingAs($this->user)->patch(route('editProduct', ['user' => $this->user->id, 'product' => $product->id]), [
        'title' => 'Updated product',
        'description' => 'Updated Product description',
        'price' => 1000,
        'visible' => true,
    ]);

    // 断言数据库中存在更新后的数据
    $this->assertDatabaseHas('products', [
        'id' => $product->id,
        'title' => 'Updated product',
        'price' => 1000,
        'visible' => 1,
    ]);

    // 或刷新实例后断言属性
    $updatedProduct = $product->refresh();
    $this->assertEquals('Updated product', $updatedProduct->title);
}

内容的提问来源于stack exchange,提问作者ШайтанЯкубович

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:30:51