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

Rails 6下如何在RSpec功能测试中阻止单条Car记录销毁?

解决方案

要在不修改Car模型代码的前提下,模拟单条记录删除失败的场景,核心思路是在测试中对目标Car实例的destroy方法进行Stub,强制它返回失败结果,这样destroy_all执行时只会跳过该记录,其他记录正常删除。

具体实现步骤

  1. 在测试中先定位要设置删除失败的Car实例
  2. 在触发删除操作(点击"Yes"按钮)之前,Stub该实例的destroy方法,让它返回false(或模拟抛出异常,视业务逻辑而定)
  3. 执行删除操作后验证结果

调整后的测试代码示例

context 'when at least one car is not deleted, but the rest are' do
  it "should display the partial success message and list undeleted cars" do
    expect(Car.count).to eq(100)
    visit bulk_edit_cars_path
    select(@location.name.upcase, from: 'Location')
    select(@track.name.upcase, from: 'Track')
    click_button("Search".upcase)

    # 选定要测试的3辆车,标记其中1辆为删除失败目标
    failed_car = Car.first
    selected_cars = [failed_car, Car.second, Car.third]

    # 勾选车辆复选框
    selected_cars.each do |car|
      find_field("cars_to_edit[#{car.id}]").click
    end
    click_button('Delete cars')

    # Stub失败车辆的destroy方法,强制返回false(不删除)
    allow(failed_car).to receive(:destroy).and_return(false)
    # 若需要模拟数据库级别的删除失败,可改用抛出异常:
    # allow(failed_car).to receive(:destroy).and_raise(ActiveRecord::RecordNotDestroyed)

    # 确认删除
    click_button('Yes')

    # 验证页面提示和数据库状态
    expect(page).to have_text(
                      'Some selected cars have been successfully deleted from the portal, however, some have not. The '
                      "following cars have not been deleted from the portal:\n\n#{failed_car.car_number}".upcase
                    )
    expect(Car.count).to eq(98)
    expect(Car.where(id: selected_cars.map(&:id)).count).to eq(1)
  end
end

原理说明

  • destroy_all会遍历集合中的每个实例,依次调用它们的destroy方法
  • 我们Stub的是从数据库中取出的真实Car实例,所以控制器中Car.where(id: params[:car_ids])的查询能正常包含该记录,解决了之前用Spy导致的记录不存在问题
  • 当目标实例的destroy被Stub返回false时,这条记录不会被删除,其他实例的destroy会正常执行,实现"部分成功"的场景

注意事项

  • 如果你的destroy_all是在全局事务中执行的,抛出异常可能导致整个事务回滚(所有记录都不删除),这种情况下建议用and_return(false)而不是抛出异常
  • 确保Stub操作在触发删除(点击"Yes")之前执行,否则无法拦截到destroy调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:50:38