ruby-on-rails 为一个具有RSpec 2的规范关闭事务性固定装置

utugiqy6  于 2023-01-18  发布在  Ruby
关注(0)|答案(7)|浏览(112)

如何在RSpec 2中仅为一个规范(或Steak场景)关闭事务性fixture?我尝试了一些在Web上找到的方法,但没有任何成功。
这会导致未定义方法异常。

describe "MyClass without transactional fixtures" do
  self.use_transactional_fixtures = false
  ...
end

这根本不起任何作用(事务性fixture仍处于打开状态):

describe "MyClass without transactional fixtures" do
  RSpec.configure do |config|
    config.use_transactional_fixtures = false
  end
  ...
end

我还能做什么?

8ulbf1ek

8ulbf1ek1#

我通常会添加这样的助手:

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

这允许我关闭规范中特定块的事务性fixture:

describe "doing my thing" do
  without_transactional_fixtures do
    it "does something without transaction fixtures" do
      ...
    end
  end
end
bhmjp9jg

bhmjp9jg2#

为了测试使用事务的代码(这将与transactional_fixture或任何其他进行事务测试的策略相冲突,例如DatabaseCleaner.strategy =:truncation或:transaction),我使用了database_cleaner:

# 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

在我的测试案例中

it "should not save if one of objects are invalid", :testing_transactions => true
ruoxqz4g

ruoxqz4g3#

这曾经是一个bug(参见ticket #197),但是我现在似乎没事了。我只是不知道它是否能在每个测试库上工作(可能不行)。如果你想这样做,你可以通过把config.use_transactional_fixtures = false放在spec_helper.rb上并使用DatabaseCleaner来设置全局事务性fixture。
我在浏览器上测试javascript页面时也遇到过类似的问题(这种情况不适用于事务性fixture),下面是我如何解决这个问题的:http://github.com/lailsonbm/contact_manager_app

rryofs0p

rryofs0p4#

我混合了这两个答案,它对我的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

然后可以在describe、context或it块中使用它

describe 'my test', use_transactional_fixtures: false do
   ...
end
z6psavjg

z6psavjg5#

不确定这是否适用于RSpec 2,但适用于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

请注意use_transactional_fixtures(rspec-rails选项)和use_transactional_tests(activerecord固定装置选项)的区别。

svdrlsy4

svdrlsy46#

当使用Rspec 2.3.8时,使用use_transactional_tests代替use_transactional_fixtures

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
lnlaulya

lnlaulya7#

RSpec 6.0的2023年答案:

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

相关问题