2015-07-27 2 views
0

У меня есть метод Rails 4.2.0, который использует пессимистическую блокировку, чтобы изменить счетчикRSpec изменение ожидания не удается при использовании активной записи пессимистической блокировок

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!reloads the parent association to get the lock и, таким образом, вы изменяете другой экземпляр, чем rspec has bound its own lambda to. Самым простым способом исправить это использовать change { } синтаксис, который не связывает экземпляр приемника к foo.parent, но вместо этого просто foo, который не меняется, как так:

expect{foo.bump!}.to change{foo.counter}.by(1) 
expect{foo.bump!}.to change{foo.parent.counter}.by(1) 

Это исправление работал на местном уровне для меня.

+0

Он также работал для меня. Отличное объяснение. –

Смежные вопросы