如何在Rails

时间:2018-06-01 15:45:29

标签: ruby-on-rails rspec optimistic-locking

我需要测试乐观锁定的实现是否正确。但我不知道如何测试我的功能。这是我写的更新动作:

def update
    begin
      @update_operator = Operator.find(params[:id])
      authorize! :update, @update_operator
      if @update_operator.update_attributes(operator_params)
        render json: @update_operator, except: :badge
      else
        render json: @update_operator.errors, status: :unprocessable_entity
      end
    rescue ActiveRecord::StaleObjectError
      @update_operator.reload
      retry
    end
  end

这是我添加的迁移

class AddLockingColumnsToOperators < ActiveRecord::Migration[5.1]
  def up
    add_column :operators, :lock_version, :integer, :default => 0, :null => false
  end

  def down
    remove_column :operators, :lock_version
  end
end

有谁能告诉我如何使用rspec测试上面的更新操作?

更新:这是我尝试的尝试,但它无法正常工作

let!(:operator1) { FactoryBot.create(:operator, :site => site) }
let!(:attributes) {
      {
        id: operator1.id,
        first_name: "test1",
        last_name: "test2",
        employee_number: "tesnt12345",
        badge: "test215235",
        suspended: true,
        site_id: site.id
      }
    }
    let!(:stale_attributes) {
      {
        id: operator1.id,
        first_name: "test_fake",
        last_name: "test_fake",
        employee_number: "tesnt12345",
        badge: "test215235",
        suspended: true,
        site_id: site.id
      }
    }

it("cause StaleObjectError when updating same operator at the same time") do
        patch :update, params: { :id => operator1.id, :operator => attributes }
        patch :update, params: { :id => operator1.id, :operator => stale_attributes }
        expect(response).to raise_error(ActiveRecord::StaleObjectError)
      end

1 个答案:

答案 0 :(得分:0)

您需要一个乐观锁定失败的测试用例。

  1. 首先获取您的编辑表单。
  2. 然后从独立更新中更新记录。
  3. 然后提交编辑表格。
  4. 在功能测试中,它可能如下所示:

    visit "/operators/#{operator.id}/edit"
    
    indep_operator = Operator.find(operator.id)
    indep_operator.update!( ... some attributes ...)
    
    fill_in "Name", :with => "New Value"
    click_button "Update Operator"