RSpec测试ads#create动作失败:预期3XX重定向却返回200 OK
排查ads#create测试重定向失败的思路
看起来你遇到的问题很典型——浏览器里功能正常,但测试没通过,核心是测试里的response不是预期的重定向而是200 OK。我来给你梳理几个最可能的排查方向:
1. 测试根本没触发create动作
你当前的测试代码只是用FactoryBot创建了一个Ad,但完全没有发送POST请求到ads#create接口!浏览器里是用户提交表单触发的create动作,但测试是孤立的,必须主动调用请求方法才能触发控制器逻辑。
修改测试,先发送创建请求:
describe "ads#create action" do let(:user) { FactoryBot.create(:user) } before do sign_in user # 先处理登录,后面会讲原因 end it "redirects to ads#show" do # 发送POST请求到create动作,参数要符合你的ad_params要求 post ads_path, params: { ad: { title: "测试广告", content: "测试内容" } } # 用Ad.last获取刚创建的广告,或者直接用assigns(:ad) expect(response).to redirect_to ad_path(Ad.last) end end
2. 测试中未设置登录用户
你的create动作依赖current_user.ads.create,如果测试环境里没有登录用户,current_user就是nil,调用nil.ads.create会触发错误,Rails可能会返回默认的错误页面(200状态)而不是执行重定向。
如果用Devise做身份验证,在测试里用sign_in方法登录一个测试用户;如果是自定义登录逻辑,要手动设置session或者current_user变量。
3. 参数不符合模型验证,创建失败
如果你的Ad模型有验证规则(比如title不能为空),而测试里传的参数不满足验证,current_user.ads.create会返回一个无效的Ad对象。如果你的控制器里有判断逻辑(比如下面这样),就会渲染new页面返回200:
def create @ad = current_user.ads.build(ad_params) if @ad.save redirect_to ad_path(@ad) else render :new # 这里返回200 end end
检查测试参数是否符合模型验证,或者用FactoryBot的有效参数来构建请求:
post ads_path, params: { ad: FactoryBot.attributes_for(:ad) }
4. 查看response的具体内容
可以在测试里临时加代码,打印返回的页面内容,直观判断为什么返回200:
it "redirects to ads#show" do post ads_path, params: { ad: { ... } } puts response.body # 控制台会输出返回的HTML内容 # 或者用launchy的save_and_open_page打开页面查看 save_and_open_page expect(response).to redirect_to ad_path(@ad) end
内容的提问来源于stack exchange,提问作者swilliams
相关产品推荐
相关产品推荐

