Turn off transactional fixtures for one spec with RSpec 2
How do I turn off transactional fixtures for only one spec (or Steak scenario) with RSpec 2? I tried some things found on the web without any success.
This leads to an undefined method exception.
describe "MyClass without transactional fixtures" do self.use_transactional_fixtures = false ... end
This simply does nothing (transactional fixture is still on):
describe "MyClass without transactional fixtures" do RSpec.configure do |config| config.use_transactional_fixt开发者_开发百科ures = false end ... end
What else could I try?
I usually add a helper like this:
def without_transactional_fixtures(&block)
self.use_transactional_fixtures = false
before(:all) do
DatabaseCleaner.strategy = :truncation
end
yield
after(:all) do
DatabaseCleaner.strategy = :transaction
end
end
Which lets me turn off transactional fixtures for a specific block in the specs:
describe "doing my thing" do
without_transactional_fixtures do
it "does something without transaction fixtures" do
...
end
end
end
I've did it this way, with database_cleaner, in order to test code that uses transactions (which will conflict with transactional_fixtures or any other strategy to make transactional tests e.g. DatabaseCleaner.strategy = :truncation or :transaction):
# spec_helper.rb
config.use_transactional_fixtures = false
config.around(:each, :testing_transactions => true) do |ex|
DatabaseCleaner.strategy = nil
ex.run
DatabaseCleaner.strategy = :truncation
end
and in my test cases:
it "should not save if one of objects are invalid", :testing_transactions => true
This used to be a bug (see ticket #197), but I seems to be okay now. I just don't know if it will work on a per test base (probably not). If you want to do this, you can disable transactional fixtures globally by putting config.use_transactional_fixtures = false
on the spec_helper.rb
and use DatabaseCleaner to set that.
I've had a similar problem when testing pages with javascript on the browser (a scenario that does not work with transactional fixtures). Here's how I managed to work around it: http://github.com/lailsonbm/contact_manager_app
I mixed both answers and it worked for me on RSpec 3:
config.around(:each, use_transactional_fixtures: false) do |example|
self.use_transactional_fixtures = false
example.run
self.use_transactional_fixtures = true
DatabaseCleaner.clean_with(:deletion)
end
You can then use it in the describe, context or it block
describe 'my test', use_transactional_fixtures: false do
...
end
Not sure if that applies to RSpec2, but works fine with 3.
config.use_transactional_fixtures = true
config.around(:each, use_transactional_fixtures: false) do |example|
self.use_transactional_tests = false
example.run
self.use_transactional_tests = true
end
Mind the use_transactional_fixtures
(rspec-rails option) and use_transactional_tests
(activerecord fixtures option) difference.
Use use_transactional_tests
instead of use_transactional_fixtures
When Rspec 2.3.8 is being used
def without_transactional_fixtures(&block)
self.use_transactional_tests = false
before(:all) do
DatabaseCleaner.strategy = :truncation
end
yield
after(:all) do
DatabaseCleaner.strategy = :transaction
end
self.use_transactional_tests = true
end
The 2023 answer for RSpec 6.0:
uses_transaction "doesn't run in transaction"
it "doesn't run in transaction" do
expect(ActiveRecord::Base.connection.transaction_open?).to eq(false)
end
it "runs in transaction" do
expect(ActiveRecord::Base.connection.transaction_open?).to eq(true)
end
https://github.com/rspec/rspec-rails/blob/v6.0.1/spec/rspec/rails/fixture_support_spec.rb#L21
精彩评论