Я пытался протестировать поведение, которое требует вложенной транзакции для отката родительских транзакций, но это просто не работает, как ожидалось.
В соответствии с другими SO Q / A и документацией вам необходимо:
do transaction(joinable: false, requires_new: true)
для дочерних транзакций, с которыми я сделал:
def some_method(child_transaction: false)
Conn.transaction(joinable: !child_transaction, requires_new: child_transaction) do
# Some Active reciord stuff
end
end
Вам нужно отключить транзакции для тестов, которые я сделал через помощника:
config.around(:each, use_transactional_fixtures: false) do |example|
self.use_transactional_tests = false
example.run
self.use_transactional_tests = true
end
И используется так:
it 'does not create a record', use_transactional_fixtures: false do
expect { subject }.not_to(change(ModelName, :count))
end
Теперь я сделал это и один из тестов, чтобы доказать, что транзакции работают
проходит, проблема в спецификации, которая доказывает, что вложенные транзакции делают, как и ожидалось, просто не работают.
Бит, который я тестирую, выглядит так:
def some_method
ActiveRecord::Base.transaction do
record = Model.new
# some code
record.method_which_contains_transaction(child_transaction: true)
# some more code
end
end
class Model < ActiveRecord::Base
def method_which_contains_transasction(child_transaction: false)
transaction(joinable: !child_transaction, requires_new: child_transaction) do
stubbed_method
end
end
end
и спецификации , как это:
describe 'some_method' do
before do
allow(Model).to
receive(:stubbed_method).and_raise(ActiveRecord::Rollback)
cost
end
it 'does not create a record', use_transactional_fixtures: false do
expect { subject }.not_to(change(Model, :count))
end
end
Я просто не уверен, почему это не работает, я явно что-то делаю неправильно, я просто не вижу, что это такое, почему дочерняя транзакция не вызывает откат в родительской транзакции как ну как я ожидаю?
Спецификация не работает с чем-то вроде expected Model count to not change but it did