Ожидание изменения rspec не выполняется при использовании активной пессимистической блокировки записи
У меня есть Rails 4.2.0
метод, который использует пессимистическую блокировку для изменения счетчика
class Foo < < ActiveRecord::Base
def bump!
transaction do
lock!
parent.lock!
lock.counter += 1
parent.counter += 1
save!
parent.save!
end
end
end
я использую Rspec 3.1
чтобы проверить это так
expect{foo.bump!}.to change(foo, :counter).by(1)
expect{foo.bump!}.to change(foo.parent, :counter).by(1)
Первый change(foo, :counter)
тест проходит, но второй change(foo.parent, :counter)
не удается, если я не закомментирую оба lock!
а также parent.lock!
Если я перепишу провальный тест, как это, он проходит
prev_counter = foo.parent.counter
foo.bump!
expect(foo.parent.counter).to eq prev_counter + 1
Почему это не работает с expect{...}.to change
?
1 ответ
Ваша проблема в том, что экземпляр foo.parent
в вашем тесте RSpec это не тот же экземпляр parent
что твой Foo#bump!
метод модифицируется, потому что вызов parent.lock!
перезагружает родительскую ассоциацию, чтобы получить блокировку, и, таким образом, вы изменяете экземпляр, отличный от rspec, к которому привязана его собственная лямбда. Самое простое решение - использовать change { }
синтаксис, который не привязывает экземпляр получателя к foo.parent
но вместо этого просто foo
, который не меняется, вот так:
expect{foo.bump!}.to change{foo.counter}.by(1)
expect{foo.bump!}.to change{foo.parent.counter}.by(1)
Это исправление работало локально для меня.