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
相关产品推荐
相关产品推荐

