Rails Capybara Test具有空实例变量

时间:2013-04-24 02:55:23

标签: ruby-on-rails rspec capybara factory-bot poltergeist

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

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

Spec传球。什么 - ?这必须是FactoryGirl问题,或者由于某种原因我的记录在运行测试之前被删除了?在创建对象后对其进行安慰会显示带有ID的记录,我想这并不能证明它将它们放在数据库中......

2 个答案:

答案 0 :(得分:1)

原来我的spec_helper中定义的数据库清理器活动有点过于活跃。我有:

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

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

答案 1 :(得分:0)

嗨,我瞥了一眼这个问题,不确定你是否还需要帮助,但我认为这个失败的原因是一个基本的设置问题,你的答案只是在修补。

当您运行Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<IsStudyingViewController 0x15cd7c180> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key back.'规范时(js: true应位于js: true行,而不是describe行),短版本,Capybara在不同的线程中工作,因此在it块中创建的实例变量与常规Rspec测试不同,在规范中不可用。要使它们可用,您必须使用before清洁策略。

truncation

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