2013-10-17 26 views
0

我是Rails的新手,目前我正在嘗試爲提交表單編寫測試。它應該測試表單是否可以爲Deal模型創建新記錄。這是失敗的,因爲我嘗試創建的社區對象顯然並未實際顯示在下拉列表中。我想知道這個記錄是不是由於某種原因而被創建的,或者是沒有被保留下來。爲什麼在我的Capybara/Rspec測試中爲數據庫記錄獲取ElementNotFound錯誤?

我得到的錯誤是

Failure/Error: select community.name, :from => "deal[community_id]" 
Capybara::ElementNotFound: 
Unable to find option "Community7" 

這裏是我的規格的相關部分:

describe "Deal Pages" do 

    subject {page} 

    describe "create Deal" do 
    let(:user) { FactoryGirl.create :user, username: "user_1", email: "[email protected]", password: "password" } 
    let(:community) { FactoryGirl.create :community, name: "Community7", title: "Community 7", description: "A great community", user: user } 

    before(:each) do 
     sign_in user 
     visit new_deal_path 
    end 

    let(:submit) { "Submit Deal" } 

    describe "with invalid information" do 

     it "should not create a Deal" do 
     expect { click_button submit }.not_to change(Deal, :count) 
     end 

     describe "after submission" do 
     before { click_button submit } 

     it { should have_title('Submit A New Deal') } 
     it { should have_content('error') } 
     end 
    end 

    describe "with valid information" do 

     it "should create a Deal" do 
     fill_in "Title",   with: "A New Deal" 
     select community.name, :from => "deal[community_id]" 
     fill_in "Url",  with: "http://www.amazon.com" 
     fill_in "Description",  with: "This is the best Deal!" 

     expect { click_button submit }.to change(Deal, :count).by(1) 
     end 
    end 
    end 

我使用的database_cleaner寶石,我知道與配置將清理每個示例後的db記錄。無論出於何種原因,這件事只是給了我很多麻煩。

spec_helper.rb

require 'rubygems' 
require 'spork' 

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

    # Requires supporting ruby files with custom matchers and macros, etc, 
    # in spec/support/ and its subdirectories. 
    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 

    # Checks for pending migrations before tests are run. 
    # If you are not using ActiveRecord, you can remove this line. 
    ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) 

    RSpec.configure do |config| 
    # ## Mock Framework 
    # 
    # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 
    # 
    # config.mock_with :mocha 
    # config.mock_with :flexmock 
    # config.mock_with :rr 

# Devise support 
#config.include Devise::TestHelpers, :type => :controller 

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

config.before(:each) do 
    DatabaseCleaner.start 
    Rails.logger.debug "DB Clean start" 
end 

config.after(:each) do 
    DatabaseCleaner.clean 
    Rails.logger.debug "DB Clean clean" 
end 

# 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. 

#for database_cleaner 
config.use_transactional_fixtures = false 

# 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 the Capybara DSL so that specs in spec/requests still work. 
config.include Capybara::DSL 
# Disable the old-style object.should syntax. 
config.expect_with :rspec do |c| 
    c.syntax = :expect 
end 


end 
end 

Spork.each_run do 
    # This code will be run each time you run your specs. 

end 

factories.rb

FactoryGirl.define do 
    factory :user do 
    sequence(:username) { |n| "Person_#{n}" } 
    sequence(:email) { |n| "person_#{n}@example.com" } 
    password "password" 
    password_confirmation "password" 
    end 

    factory :community do 
    sequence(:name) { |n| "Community#{n}" } 
    sequence(:title) { |n| "Community #{n} Title" } 
    sequence(:description) { |n| "a great community #{n}" } 
    user 
    end 

    factory :deal do 
    sequence(:title) { |n| "Great Deal #{n}" } 
    url "http://www.amazon.com" 
    sequence(:description) { |n| "deal #{n} rocks so click it" } 
    user 
    community 
    end 
end 

回答

2

好,我想通了一段時間回來,因爲我討厭我通過Google找到未解答的問題,我會跟進。

的問題是,我有我的父母的頂部以下描述塊:

let(:community) { FactoryGirl.create :community, name: "Community7", title: "Community 7", description: "A great community", user: user } 

有這個問題,除了不需要指定單獨的屬性,是當與database_cleaner配置相結合,它會在每個示例後轉儲數據庫。在「創建交易」塊之前有一個或多個示例,因此在調用community.name時,社區表中沒有數據。我改變了我的天賦念想的話,我覺得是我更容易處理,並按照:

describe "create Deal" do 

    before(:each) do 
     @user = FactoryGirl.create :user 
     @community = FactoryGirl.create :community 
     sign_in @user 
     visit new_deal_path 
    end 

    let(:submit) { "Submit Deal" } 

    describe "with invalid information" do 

     it "should not create a Deal" do 
      expect { click_button submit }.not_to change(Deal, :count) 
     end 

     describe "after submission" do 
      before { click_button submit } 

      it { should have_title('Submit A New Deal') } 
      it { should have_content('error') } 
     end 
    end 

    describe "with valid information" do 

     it "should create a Deal" do 
      fill_in "Title",   with: "A New Deal" 
      select @community.name, :from => "deal[community_id]" 
      fill_in "Url",  with: "http://www.amazon.com" 
      fill_in "Description",  with: "This is the best Deal!" 

      expect { click_button submit }.to change(Deal, :count).by(1) 
     end 
    end 
end 

的前(:每個)確保我的每一個孩子的例子之前取得一個新的用戶和社區對象正在運行。希望這有助於某人,但如果不是,那對我來說是一種學習體驗。

1

的問題是,你通過 「Community7」 在

let(:community) { FactoryGirl.create :community, name: "Community7", title: "Community 7", description: "A great community", user: user } 

而 「社區」 這個詞也通過工廠添加:社區:

factory :community do 
    sequence(:name) { |n| "Community#{n}" } 
    sequence(:title) { |n| "Community #{n} Title" } 
    ... 
end 

因此,您得到「CommunityCommunity7」和相應的錯誤:

Unable to find option "Community7" 

我會調整工廠作爲

factory :community do 
    sequence(:name) { |n| "#{n}" } 
    sequence(:title) { |n| "#{n} Title" } 
    ... 
end 
+0

嗯。這是我的理解,通過提供這些屬性,我壓倒了工廠定義的內容。我沒有看到它將「CommunityCommunity7」放入數據庫中。它把「社區7」。我選擇重寫它的原因是試圖找出整個事情爲什麼不起作用。我只是在嘗試不同的事情。謝謝你! – hackakhan

相關問題