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

使用RSpec 3.12测试记录失效标记时的异常问题排查

软删除测试问题排查与修复

背景情况

我的Playground控制器采用软删除逻辑:用户删除时不会真正删除记录,只是调用set_as_inactive方法把is_active标记设为false,并记录操作人。控制器代码如下:

def destroy
  @playground.set_as_inactive(current_login)
  respond_to do |format|
    format.html { redirect_to playgrounds_url, notice: t('.Success') } #'Playground was successfully deleted.'
    format.json { head :no_content }
  end
end

这个功能在实际应用里运行正常,但写请求测试时发现了问题:测试代码中Playground.visible(仅返回活跃记录)的计数确实减了1,但直接检查playground_tbd.is_active却还是true。测试代码如下:

describe "DELETE /destroy" do
  let(:playground_tbd) { create(:playground) }
  it "destroys the requested playground" do
    expect {
      delete playground_url(playground_tbd)
    }.to change(Playground.visible, :count).by(-1) 
    expect(response).to have_http_status 302
    expect(response).to redirect_to(playgrounds_url)
  end
  it "renders the expected status" do
    get playground_url(playground_tbd)
    expect(playground_tbd.is_active).to eq(false)
  end
end

问题根源

你漏了两个关键细节:

  • 第二个测试没执行删除操作
    RSpec的每个it块都是独立运行的,彼此之间数据库状态会回滚重置。第二个测试里只执行了get请求,根本没调用DELETE接口去标记记录失效,所以playground_tbd还是刚创建时的活跃状态。

  • 内存对象不会自动同步数据库变更
    就算你在测试里执行了DELETE操作,内存里的playground_tbd对象也不会自动更新,必须调用reload方法从数据库重新读取,才能拿到最新的is_active值。

修正后的测试代码

describe "DELETE /destroy" do
  let(:playground_tbd) { create(:playground) }

  it "destroys the requested playground" do
    expect {
      delete playground_url(playground_tbd)
    }.to change(Playground.visible, :count).by(-1) 
    expect(response).to have_http_status 302
    expect(response).to redirect_to(playgrounds_url)
  end

  it "marks the playground as inactive" do
    # 先执行软删除操作
    delete playground_url(playground_tbd)
    # 重新加载对象获取数据库最新状态
    playground_tbd.reload
    expect(playground_tbd.is_active).to eq(false)
  end
end

额外说明

  • 每个测试用例都是独立的,前一个测试的数据库变更会被回滚,所以第二个测试的playground_tbd是全新的活跃记录。
  • 控制器修改数据库后,内存中的对象实例不会自动同步,必须用reload才能验证最新属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:42:37