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

RSpec测试异常:用户密码更新接口始终返回200而非预期401

问题根源:测试中错误的参数嵌套结构

我一眼就瞅出问题出在你「current password is incorrect」分支的测试代码里——参数结构嵌套错了,导致控制器根本没触发身份验证逻辑,直接走了更新分支返回200。

具体分析

先看你控制器里的核心判断逻辑:

if params[:user].has_key?("current_password") && !(@user.authenticate(params[:user][:current_password]))

这里是直接检查params[:user]里是否包含current_password这个key。

但你的错误分支测试里,user_params的定义是:

let(:user_params) do
  { user: { current_password: "incorrect1235", password: "newpassword123" }}
end

然后你在patch请求里又套了一层user::

patch :update, params: { id: custom_user.id, user: user_params }

这就导致最终的请求参数结构变成了:

{
  id: custom_user.id,
  user: {
    user: {
      current_password: "incorrect1235",
      password: "newpassword123"
    }
  }
}

此时params[:user]是外层的那个哈希{ user: {...} },里面根本没有current_password这个key,所以控制器的if条件直接不成立,跳去执行else分支的update_attributes!,自然返回200状态码,你的401断言就失败了。

修复方案

把错误分支的user_params改成和正确分支一样的结构,去掉多余的user嵌套:

context "when current password is incorrect" do
  # 修正参数结构,和正确分支保持一致
  let(:user_params) do
    { current_password: "incorrect1235", password: "newpassword123" }
  end
  before :example do
    patch :update, params: { id: custom_user.id, user: user_params }
  end
  it "does not update user's password" do
    # 这里顺便修正:你传的错误密码是incorrect1235,之前断言写成了incorrect1234,建议统一
    expect(custom_user.authenticate('incorrect1235')).not_to eq(custom_user)
    expect(response.status).to eq(401)
  end
end

这样请求参数就会变成正确的结构:

{
  id: custom_user.id,
  user: {
    current_password: "incorrect1235",
    password: "newpassword123"
  }
}

控制器就能正确检测到params[:user]里的current_password,验证失败后返回401,你的断言就能通过了。

额外小提醒

你错误分支的断言里,authenticate用的密码和传参的密码不一致,虽然不影响状态码断言,但为了测试严谨性,建议统一起来,避免后续自己看代码时混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:47:34