rspec 使用活动记录悲观锁定时更改预期失败
rspec change expectation fails when using active record pessimistic locking
我有一个 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
?
您的问题是 RSpec 测试中的 foo.parent
实例与您的 Foo#bump!
方法正在修改的 parent
实例不同,因为调用 parent.lock!
reloads the parent association to get the lock and thus you modify a different instance than 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)
这个修复在本地对我有效。
我有一个 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
?
您的问题是 RSpec 测试中的 foo.parent
实例与您的 Foo#bump!
方法正在修改的 parent
实例不同,因为调用 parent.lock!
reloads the parent association to get the lock and thus you modify a different instance than 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)
这个修复在本地对我有效。