我想测试ActiveRecord::Base.transaction
块:
class Book < ActiveRecord::Base
has_many :revisions, class_name: 'RevisionState'
def _update(book_params)
assign_attributes book_params
if valid?
ActiveRecord::Base.transaction do
revisions.create!(state: 'draft') if save!(book_params) # save then create
# ....get create! to raise an exception
end
end
end
end
我正在使用Minitest,但这不重要。此外,我更喜欢这样做,而不依赖于一些额外的宝石 - 即如果可能的话,只需要很好的Ruby。
一个想法是覆盖(重新定义)Book.save!
(ActiveRecord.save!
)和RevisionState.create!
(ActiveRecord.create!
),另一个是注入过滤器(例如{{1} })强制异常。
测试/模型/ book_test.rb :
after_save
上述工作,除了我在 app / models / revision_change.rb 中提出异常:
require 'test_helper'
class BookTest < ActiveSupport::TestCase
test '_update transaction' do
# do some normal stuff
# ...
# And now do something to get RevisionState.create! to raise an exception
# when it is called below (via ._update) <-- need help
assert_difference('RevisionState.count', 0) do
assert_raises(RuntimeError) {
book._update({title: 'raise hell'})
}
end
book = Book.find(book.id)
refute_equal 'raise hell', book.title
end
end
显然,在我的应用中,这种黑客行为是不受欢迎的,因此我想在我的测试中在运行时进行。