我有2个模特:场地和活动。 Venue has_many:events and event belongs_to:venue。
我的活动/新表单包含以下字段
现在我正试图用RSpec和Capybara测试这个。这是我的特色:
require 'spec_helper'
feature "Events" do
let(:venue) { FactoryGirl.create(:venue) }
let(:event) { FactoryGirl.create(:event, venue: venue) }
scenario "Creating event as guest" do
visit root_path
click_link "Submit Event"
fill_in "Title", with: event.title
click_button "Submit"
expect(page).to have_content("Event has been created.")
expect(page).to have_content(event.title)
end
end
我的工厂看起来像这样:
FactoryGirl.define do
factory :event do
date "2014-02-27"
time "10:00am"
title "Slayer"
end
end
FactoryGirl.define do
factory :venue do
name "Example Venue"
url "http://www.example.com"
address "123 Main St., Chicago, IL"
end
end
当我运行此规范时,我收到以下错误:
Failure/Error: click_button "Submit"
ActionView::Template::Error:
Couldn't find Venue without an ID
我猜这与Venue字段未在测试环境中填充这一事实有关?
答案 0 :(得分:2)
使用let
是懒惰的,所以你的数据库调用将在这里执行:
scenario "Creating event as guest" do
visit root_path
click_link "Submit Event"
fill_in "Title", with: event.title # <------------------- evaluated!
click_button "Submit"
expect(page).to have_content("Event has been created.")
expect(page).to have_content(event.title)
end
你可能想要的是这个:
feature "Events" do
background do
@event = FactoryGirl.create(:event, venue: FactoryGirl.create(:venue))
end
scenario "Creating event as guest" do
visit root_path
click_link "Submit Event"
fill_in "Title", with: @event.title
click_button "Submit"
expect(page).to have_content("Event has been created.")
expect(page).to have_content(@event.title)
end
end
您也可以使用直接执行的let!
,但我认为设置块更清晰。