【问题标题】:Why are these Rspec examples not occuring within a DB transaction?为什么这些 Rspec 示例没有出现在数据库事务中?
【发布时间】:2013-06-04 17:10:54
【问题描述】:

我正在我的应用程序中编写一个典型的测试,我通过一个表单创建一个模型并检查模型计数是否等于 1。

测试失败,因为测试数据库中已经有多条记录,并且每次运行测试时该计数都会增加。看起来每个示例都没有像预期的那样发生在事务中(正在回滚),我不知道为什么。

我的 spec_helper.rb 文件中有这一行,它应该在事务中运行每个示例:

config.use_transactional_fixtures = true

这是我不断生成模型对象的规范:

require 'spec_helper'

describe "Admin artwork pages" do
  subject { page }
  let(:gallery) { FactoryGirl.create(:gallery) }

  describe "artwork creation" do
    context "with valid attributes" do
      it "creates new artwork" do
        visit admin_gallery_artworks_path(gallery_id: gallery.id)

        click_link 'Add new artwork'
        fill_in 'artwork_title', with: 'Still Life'
        click_button 'Create Artwork'

        page.should have_text 'Successfully created'
        Artwork.count.should eq 1
      end
    end
  end
end

这是来自 Rspec 的错误消息:

Failures:

1) Admin artwork pages artwork creation with valid attributes creates new artwork
 Failure/Error: Artwork.count.should eq 1

   expected: 1
        got: 153

   (compared using ==)

编辑:我的 spec_helper.rb 文件的内容:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rails'
require 'capybara/rspec'

Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config| 

# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true

# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false

# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
#     --seed 1234
config.order = "random"
# Include route helpers
config.include Rails.application.routes.url_helpers
#
# Take the FactoryGirl out of FactoryGirl.create
config.include FactoryGirl::Syntax::Methods

结束

我正在使用 Rails 4.0.0.rc1、Ruby 1.9.3、FactoryGirl 和 rspec-rails 2.13.0 感谢您的帮助。

【问题讨论】:

  • 你用的是什么数据库?
  • Rails 自带的 Sqlite3。
  • 你在使用灯具吗?
  • 你也可以粘贴你的spec_helper.rb 文件吗?
  • 也可以通过运行rake db:test:prepare来解决这个问题吗?

标签: ruby-on-rails rspec rspec-rails


【解决方案1】:

事实证明,从 rspec-rails 2.13.1 开始支持 Rails 4 - 我使用的是 2.13.0。升级后,规范在交易中发生,就像他们应该做的那样。

感谢所有花时间发布帮助的人。

【讨论】:

    【解决方案2】:

    我认为问题在于您编写测试的方式,而不是 config.use_transactional_fixtures = true。关注错误底部(compared using ==)

    尝试改用期望更改的 rspec 语法

    改变这个:

      click_button 'Create Artwork'
    
      page.should have_text 'Successfully created'
      Artwork.count.should eq 1
    

    到这里:

      expect { click_button 'Create Artwork' }.to change { Artwork, :count }.by(1)
    
      page.should have_text 'Successfully created'
    

    如果这有帮助,请告诉我

    【讨论】:

      【解决方案3】:

      您正在运行请求规范:当您调用 visit 时,被测代码在服务器实例中运行(在同一进程中)。特别是这意味着它正在使用不同的线程。

      因此,应用程序代码最终会使用不同的数据库连接,并且由于事务是每个连接的事情,因此当您的控制器将记录插入数据库时​​不会使用任何事务。

      有几种方法可以解决这个问题。一种是放弃 rspec 的事务性装置并使用 database_cleaner gem。您可以对其进行设置,以便控制器和模型规范使用事务,但请求规范使用截断来强制清除表。

      另一种方法是尝试强制规范代码和服务器代码使用相同的数据库连接,从而消除问题。您可以在this answer 中看到这种方法。以我的经验,在您开始使用水豚驱动程序(例如 poltergeist)之前,这非常有效,它将在页面上运行任何 javascript 并且您的页面会触发 ajax 请求。

      我一直使用的方法是将活动记录连接池大小设置为 1:只允许 1 个连接,因此每个人都将使用同一个。然后,您必须做一些工作以确保连接返回到池中,否则您的规范会挂起。

      我不久前将详细信息写为blog post,但简而言之,您需要

      • 在调用访问、点击等方法之前调用ActiveRecord::Base.clear_active_connections!
      • 破解 config.middleware.insert_before ActiveRecord::ConnectionAdapters::ConnectionManagement 以便在每次请求后清除连接(默认情况下它不会在测试中这样做)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 2013-10-27
        • 2018-11-26
        • 2012-10-07
        相关资源
        最近更新 更多