1

我有一个控制器向我的控制器发送供应商列表,并且在正常视图中它工作正常。

class VendorsController < ApplicationController

  respond_to :html, :json

  def index
    @vendor_categories = VendorCategory.where(:is_top_level => true)
    @vendors = Vendor.includes(:vendor_tier, :vendor_categorizations, :vendor_categories).order('vendor_tier_id DESC, name ASC')

    respond_with @vendors
  end
end

在我看来,我有以下两行:

= debug @vendors
= debug current_user.user_vendor_choices

如果我在浏览器中查看它,它再次起作用。但是,如果我用 Capybara 和 RSpec 测试它,它是空的。

require 'spec_helper'

describe 'Vendors' do
  before do
    category = create(:vendor_category)

    5.times do 
      vendor = create(:vendor)
      vendor_categorization = create(:vendor_categorization, vendor: vendor, vendor_category: category)
      p vendor
      p category
      p vendor_categorization
    end

    visit signup_path

    @new_user = sign_up
  end

  before(:each) do
    visit destroy_user_session_path
    visit new_user_session_path
    sign_in @new_user
    visit vendors_path
  end

  it 'should save selected vendors', js: true do
    p Vendor.includes(:vendor_tier, :vendor_categorizations, :vendor_categories).order('vendor_tier_id DESC, name ASC').count
  end

end

Vendor.all和上面Vendor.includes...两个返回值,但由于某种原因在我的测试中它没有显示任何东西......得到一个Capybara::Element not found.

更新

出于测试目的,我直接使用控制器创建了供应商:

  def index

    @vendor_categories = VendorCategory.where(:is_top_level => true)
    4.times do
      Vendor.create({name: 'Test McTesterson', vendor_tier_id: 1})
    end
    @vendors = Vendor.includes(:vendor_tier, :vendor_categorizations, :vendor_categories).order('vendor_tier_id DESC, name ASC')

    respond_with @vendors
  end

规范通过。什么——?这一定是 FactoryGirl 问题,或者由于某种原因,我的记录在运行测试之前被删除了?在我创建对象后对它们进行安慰显示了一条带有 ID 的记录,我想这并不能证明它正在将它们放入数据库中......

4

2 回答 2

1

原来我在我的 spec_helper 中定义的 Database Cleaner 活动有点过于活跃了。我有:

RSpec.configure do |config|

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

我必须摆脱第二个块,所以它现在显示:

RSpec.configure do |config|

  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

end

它有效!不太清楚为什么......任何想法(除了显而易见的,在每次测试之前/之后调用数据库清理器之前)?

于 2013-04-25T02:23:17.110 回答
0

嗨,我粗略地看了一眼这个问题,不确定您甚至是否需要帮助,但我认为这失败的原因是您的答案只是修补的基本设置问题。

当您运行js: true规范时(顺便说一句,js: true应该describe在线,而不是it在线),短版本,Capybara 在不同的线程中工作,因此在before块中创建的实例变量与常规 Rspec 测试不同,在规范。为了使它们可用,您必须使用truncation清洁策略。

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

TL;DR 在运行 js 测试时,基本上需要截断(除非显然您正在运行不需要任何数据库交互的 js 测试)。在运行所有其他测试时,使用事务(因为它也快得多)。我猜你的回答在某种程度上复制了这一点=)

于 2015-06-29T01:45:20.090 回答