Вопрос

Я пытаюсь решить проблему уже несколько недель.Я запускаю тесты 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, вы должны это увидеть ;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top