0

I need to test if my implementation of optimistic locking is correct or not. But I don't know how to test my functionalities. Here is the update action I wrote:

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

And here is the migration I added

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

Can anyone tell me how to test the update action above with rspec?

Update: Here is the attempt I tried, but it didn't work

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
Darren
  • 170
  • 4
  • 18
  • In your example, in the update section, you are not getting the lock_version. You need to query the record, get the lock_version, then there is another update, then your update will be stale. – Marlin Pierce Jun 01 '18 at 17:23

1 Answers1

0

You want a test case where optimistic locking fails.

  1. First get your edit form.
  2. Then update the record from an independent update.
  3. Then submit the edit form.

In a functional test it might look like this:

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"
Marlin Pierce
  • 9,931
  • 4
  • 30
  • 52
  • Yeah, I tried the similar way, but it didn't work to me. You can check my attempt and tell me if I need to change anything – Darren Jun 01 '18 at 17:12