Rails test db не сохраняет изменения записи
-
23-09-2019 - |
Вопрос
Я пытаюсь решить проблему уже несколько недель.Я запускаю тесты rspec для своего приложения Rails, и они работают нормально, за исключением одной ошибки, которая, похоже, не укладывается у меня в голове.
- Я использую MySQL с движком InnoDB.
- Я установил
config.use_transactional_fixtures = true
в spec_helper.rb - Я загружаю свои тестовые устройства вручную с помощью команды
rake spec:db:fixtures:load
. - Тест rspec пишется для backgrounddrb worker, и он проверяет, что запись может обновлять свое состояние (через драгоценный камень 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
и т.д.
Спасибо, что прочитали это, и, пожалуйста, задавайте любые вопросы, если я не предоставил достаточно информации.
Спасибо за вашу помощь, Натан Би
P.S.У меня не возникает проблем с созданием новых записей для других классов и тестированием этих записей.Это кажется проблемой только тогда, когда я обновляю записи, которые уже существуют в базе данных.
Решение
Я подозреваю, как и Натан, проблемы с транзакциями.Попробуйте поместить Listing.connection.execute ("COMMIT") прямо перед вашим первым вызовом сохранения, чтобы прервать транзакцию и посмотреть, что изменится.Это выведет вас из транзакции, поэтому любые дополнительные вызовы отката будут неэффективными.
Кроме того, выполнив команду "COMMIT", вы можете приостановить тест с помощью отладчика и проверить базу данных с другого клиента, чтобы увидеть, что происходит.
Другая гипотеза, если эксперименты с транзакциями не дают никаких результатов, заключается в том, что, возможно, ваша модель действительно не сохраняется в базе данных.Проверьте свои журналы запросов.(В частности, найдите запрос на обновление).
Такого рода проблемы действительно воняют!Удачи вам!
Другие советы
Если вы хотите исследовать, что у вас есть в базе данных во время выполнения тестов, это может оказаться полезным...
У меня есть тест rspec, в котором я сохраняю @user.save, и это работает как по волшебству, но потом я хотел посмотреть, действительно ли это сохранено в базе данных.
Я открыл консоль rails для тестовой среды
rails c test
побежал
User.all
и, как и ожидалось, ничего не получил
Я запустил свою спецификацию, которая содержит:
user_attr_hash = FactoryGirl.attributes_for(:user)
@user = User.new user_attr_hash
@user.save
binding.pry
Я думал, что остановка теста после сохранения будет означать, что он сохраняется, но это не так.Похоже, что ФИКСАЦИЯ при соединении запускается позже (я понятия не имею, когда:\ ) Итак, как предлагает @Tim Harper, вы должны запустить эту фиксацию самостоятельно в консоли pry:
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")
Теперь, если вы запустите User.all в своей консоли rails, вы должны это увидеть ;)