Rails test db не сохраняет записи изменений - PullRequest
2 голосов
/ 30 марта 2010

Я пытаюсь решить проблему в течение нескольких недель. Я запускаю тесты rspec для моего приложения на Rails, и они работают нормально, за исключением одной ошибки, которую я, кажется, не могу понять.

  • Я использую MySQL с движком InnoDB.
  • Я установил config.use_transactional_fixtures = true в spec_helper.rb
  • Я загружаю свои испытательные приборы вручную с помощью команды rake spec:db:fixtures:load.
  • Тест rspec пишется для работника BackgrounDRb, и он проверяет, может ли состояние записи обновляться (через гем state_machine).

Вот моя проблема:

У меня есть модель под названием Listings. Тест rspec вызывает метод update_sold_items в файле с именем listing_worker.rb. Этот метод вызывает listing.sell для конкретной записи, которая устанавливает для столбца «state» записи листинга значение «sold». Пока что все работает нормально, но когда метод update_sold_items завершается, мой тест rspec завершается неудачно:

listing = Listing.find_by_listing_id(listing_id)
listing.state.should == "sold"

expected: "sold",
     got: "current" (using ==)

Я пытался выяснить, почему изменение состояния не сохраняется, но в значительной степени потеряно. Вот результат некоторого кода отладки, который я поместил в метод update_sold_items во время теста:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

Я не могу понять, почему это прекрасно экономит, но затем возвращается к исходной записи всякий раз, когда я звоню reload или Listing.find и т. Д.

Спасибо, что прочитали это, и, пожалуйста, задавайте любые вопросы, если я не предоставил достаточно информации.

Спасибо за вашу помощь, Натан Б

P.S. У меня нет проблем с созданием новых записей для других классов и тестированием этих записей. Кажется, это только проблема, когда я обновляю записи, которые уже существуют в базе данных.

Ответы [ 2 ]

1 голос
/ 30 марта 2010

Подозреваю, как и у Натана, проблемы с транзакциями. Попробуйте поместить Listing.connection.execute ("COMMIT") перед первым вызовом сохранения, чтобы прервать транзакцию и посмотреть, что изменится. Это выведет вас из транзакции, поэтому любые дополнительные вызовы отката будут неэффективными.

Кроме того, запустив команду «COMMIT», вы можете приостановить тест с помощью отладчика и проверить базу данных другого клиента, чтобы увидеть, что происходит.

Другая гипотеза, если эксперимент по транзакциям не дает никаких результатов, возможно, ваша модель действительно не сохраняется в базе данных. Проверьте ваши журналы запросов. (Конкретно найдите запрос на обновление).

Эти проблемы действительно воняют! Удачи!

0 голосов
/ 30 мая 2014

Если вы хотите исследовать, что у вас есть в БД во время выполнения тестов, вы можете найти это полезным ...

У меня есть тест rspec, где я сохраняю @ user.save, и он работает как чудо, но потом я хотел посмотреть, действительно ли он сохранен в БД.

Я открыл консоль рельсов для тестовой среды

rails c test

побежал

User.all

и, как ожидалось, ничего не получил

Я запустил свою спецификацию, которая содержит:

user_attr_hash    = FactoryGirl.attributes_for(:user)
@user = User.new user_attr_hash
@user.save
binding.pry

Я думал, что остановка теста после сохранения будет означать, что он сохраняется, но это не так. Кажется, что COMMIT на соединение запускается позже (я понятия не имею, когда: \) Итак, как подсказывает @Tim Harper, вы должны запустить этот коммит в консоли:

pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")

Теперь, если вы запустите User.all в консоли rails, вы должны увидеть это;)

...