Rspec: Транзакционные светильники не работают после обновления до рельсов 4

У меня есть следующий набор строк в spec_helper.rb

config.use_transactional_fixtures = true

Это означает, что каждый тест должен очищать после себя. Любое обновление db, сделанное одним тестом, не должно быть рядом для следующего теста.

У меня есть два теста в одном из моих файлов spec.

it 'should update the DB' do
  Setting.put('abcd', 'efgh')
end

it 'should not find the DB update' do
  Setting.get('abcd').should be_nil
end

Два вышеупомянутых теста, используемых для работы с Rails 3.2.14

Однако после обновления до Rails 4 второй тест завершился с ошибкой,

------
expected: nil
got: "efgh"
-----

У меня из-за этой проблемы из-за ошибки в пакете 100 тестов.

Единственная связанная документация, которую я могу найти для обновления Rails 4, была чем-то довольно неопределенным: "Rails 4.0 не одобряет ActiveRecord:: Fixtures в пользу ActiveRecord:: FixtureSet."

Я не уверен, насколько это важно. Я бы идеально хотел иметь глобальную настройку (config.use_transactional_fixtures = true) и не менять логику тестов (или добавлять дополнительные до (: each)/after (: each) модули только для того, чтобы пройти существующие тесты Пожалуйста, помогите!

Ответ 1

Для удаления

require 'rspec/autorun'

от spec_helper все наладилось.

У меня был сервер zeus. Признаки были, если я запускаю тест с транзакцией сервера zeus, он будет сохранен в тестовой базе данных.

Когда сервер zeus не запускался, rspec будет работать нормально.

Чтобы заставить его работать с сервером Zeus, мне пришлось автозапускать.

Ответ 2

У меня была точно такая же проблема (с rspec-rails 3.1) на рельсах 4.1. Не было автоматического запуска, хотя у меня действительно был spring, который может быть виновником. Тем не менее, я решил попробовать альтернативу, которая хорошо работала: очистка базы данных, которая выполняет аналогичную работу: https://github.com/DatabaseCleaner/database_cleaner

Итак, добавьте в Gemfile:

group :test do
...
  gem 'database_cleaner'
...
end

Затем перейдите к помощнику rails:

  #Database cleaning
  config.use_transactional_fixtures = false #IMPORTANT, make sure that rails doesn't try and clean it
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction #usually use transaction as the strategy - this is what transaction_fixtures does
    DatabaseCleaner.clean_with(:truncation) # I like to ensure my database is in clean state to start with so I truncate at the start of the suite - this is optional.
  end 

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end 
  end 

Ответ 3

Как один комментарий предложил, это, скорее всего, проблема с rspec-rails (https://github.com/rails/rails/issues/10376). Попробуйте перейти на rspec-rails 2.13.1 или выше:

bundle update --source rspec-rails

Ответ 4

Я не уверен, что это та же проблема. Но для меня было решение - создавать данные только в "it" do/end block. И если вы создаете данные в контексте, это не сработает.

который работает:

    context "with array of both exista and non exist words" do

      clean_words = ["foo", "bar", "foobar"]

      language = "eng"
      it "return array of word, that exist in Word class" do
        word = FactoryGirl.create(:word)
        word2 = FactoryGirl.create(:word, name: "bar")
        exist_words = [word, word2]
        expect(Word.generate_list_of_exist_words(clean_words, language).sort).to eq exist_words.sort

      end
    end

который не работает:

    context "with array of both exista and non exist words" do

      clean_words = ["foo", "bar", "foobar"]
      word = FactoryGirl.create(:word)
      word2 = FactoryGirl.create(:word, name: "bar")
      exist_words = [word, word2]
      language = "eng"
      it "return array of word, that exist in Word class" do

        expect(Word.generate_list_of_exist_words(clean_words, language).sort).to eq exist_words.sort

      end
    end