2010-03-30 3 views
2

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

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

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

У меня есть модель под названием Listings. Тест rspec вызывает метод update_sold_items в файле с именем listing_worker.rb. Этот метод вызывает listing.sell для конкретной записи, которая устанавливает столбец состояния состояния записи «продано». До сих пор это все работает нормально, но когда метод 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 и т. д.

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

Спасибо за вашу помощь, Nathan B

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

+0

Не перезаписывайте ли транзакционные приборы при ROLLBACK при перезагрузке? Все в транзакции, чтобы они могли сбросить данные перед каждым тестом. Эта перезагрузка/ROLLBACK будет в исходном состоянии, а не в сохраненном состоянии, да? Почему вы его перезагружаете? – wesgarrison

+0

хорошо пункт. Я не был на 100% уверен, как работает транзакция. Спасибо за вашу помощь! – ndbroadbent

ответ

1

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

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

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

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

+0

Спасибо, что указал мне в правильном направлении! Наконец, я решил, что я переоцениваю метод обновления моделей и чувствую себя идиотом. Благодаря!! – ndbroadbent

0

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

У меня есть RSpec тест, где я сохранить @user.сохранить и работает как шарм, но потом я хотел посмотреть, действительно ли он сохранен в БД.

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

rails c test 

побежал

User.all 

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

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

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

I T что остановка теста после сохранения будет означать, что он сохраняется, но это не тот случай. Кажется, что COMMIT на связи обжигают позже (я понятия не имею, когда: \) Так что, как говорит @ Тим Харпер, вы должны стрелять, которые сами совершают в монтировки консоли:

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

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

Смежные вопросы