Rails 测试数据库不保留记录更改

发布于 2024-08-27 05:32:13 字数 1224 浏览 6 评论 0原文

几周来我一直在努力解决一个问题。我正在为我的 Rails 应用程序运行 rspec 测试,除了一个我似乎无法理解的错误之外,它们工作正常。

  • 我正在使用 MySQL 和 InnoDB 引擎。
  • 我已在spec_helper.rb中设置了config.use_transactional_fixtures = true,
  • 我使用命令rake spec:db:fixtures:load手动加载测试装置。
  • rspec 测试是为 BackgrounDRb 工作线程编写的,它正在测试记录是否可以更新其状态(通过 state_machine gem)。

这是我的问题:

我有一个名为 Listings 的模型。 rspec 测试调用 listing_worker.rb 文件中的 update_sold_items 方法。 此方法为特定记录调用 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 等。

感谢您阅读本文,如果我没有提供足够的信息,请提出任何问题。

感谢您的帮助, 内森

B.S.我为其他类创建新记录并测试这些记录没有问题。当我更新数据库中已存在的记录时,这似乎只是一个问题。

I've been trying to solve a problem for a few weeks now. I am running rspec tests for my Rails app, and they are working fine except for one error that I can't seem get my head around.

  • I am using MySQL with the InnoDB engine.
  • I have set config.use_transactional_fixtures = true in spec_helper.rb
  • I load my test fixtures manually with the command rake spec:db:fixtures:load.
  • The rspec test is being written for a BackgrounDRb worker, and it is testing that a record can have its state updated (through the state_machine gem).

Here is my problem:

I have a model called Listings. The rspec test calls the update_sold_items method within a file called listing_worker.rb.
This method calls listing.sell for a particular record, which sets the listing record's 'state' column to 'sold'.
So far, this is all working fine, but when the update_sold_items method finishes, my rspec test fails here:

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

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

I've been trying to track down why the state change is not persisting, but am pretty much lost. Here is the result of some debugging code that I placed in the update_sold_items method during the test:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

I cannot understand why it saves perfectly fine, but then reverts back to the original record whenever I call reload, or Listing.find etc.

Thanks for reading this, and please ask any questions if I haven't given enough information.

Thanks for your help,
Nathan B

P.S. I don't have a problem creating new records for other classes, and testing those records. It only seems to be a problem when I am updating records that already exist in the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

找个人就嫁了吧 2024-09-03 05:32:13

我和内森一样怀疑交易问题。尝试在第一次保存调用之前放置 Listing.connection.execute("COMMIT") 以中断事务并查看发生了什么变化。这将使您脱离事务,因此任何额外的回滚调用都将无效。

此外,通过运行“COMMIT”命令,您可以使用调试器暂停测试并从另一个客户端检查数据库以查看发生了什么。

另一个假设是,如果事务实验没有产生任何结果,则可能您的模型确实没有保存到数据库中。检查您的查询日志。 (具体查找更新查询)。

诸如此类的问题实在是太臭了!祝你好运!

I suspect, like nathan, transaction issues. Try putting a Listing.connection.execute("COMMIT") right before your first save call to break the transaction and see what changes. That will break you out of the transaction so any additional rollback calls will be non-effectual.

Additionally, by running a "COMMIT" command, you could pause the test with a debugger and inspect the database from another client to see what's going on.

The other hypothesis, if the transaction experimentation doesn't yield any results, is that perhaps your model really isn't saving to the database. Check your query logs. (Specifically find the update query).

These kind of issues really stink! Good luck!

氛圍 2024-09-03 05:32:13

如果您想在运行测试时调查数据库中的内容,您可能会发现这很有帮助...

我有一个 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

我认为保存后停止测试意味着它会持续存在,但事实并非如此。看来连接上的 COMMIT 稍后会被触发(我不知道什么时候:\)
因此,正如 @Tim Harper 所建议的,您必须在 pry 控制台中触发该提交:

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

现在,如果您在 Rails 控制台中运行 User.all,您应该会看到它;)

If you want to investigate what you have in DB while running tests you might find this helpful...

I have a rspec test where I save @user.save and it works like a charm, but then I wanted to see if it's really saved in the DB.

I opened rails console for test environment

rails c test

ran

User.all

and as expected got nothing

I ran my spec that contains:

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

I thought that stopping the test after save would mean that it's persisted, but that's not the case. It seems that COMMIT on the connection is fired later (I have no idea when:\ )
So, as @Tim Harper suggests, you have to fire that commit yourself in the pry console:

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

Now, if you run User.all in your rails console you should see it ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文