我有兩個失敗的規範,似乎是某種聯繫。下面是它們:水豚不遵循重定向和修改數據庫
describe "exclude from navigation button" do
before do
within "#page_#{pages[1].id}" do
click_link I18n.t 'pages.exclude'
end
pages[1].reload
end
specify { pages[1].menu_order.should == -1 }
it "should add an excluded css class to the pages control" do
page.should have_selector "li.excluded#page_#{pages[1].id}"
end
end
describe "include in navigation button" do
before do
within "#page_#{pages[2].id}" do
click_link I18n.t 'pages.include'
end
pages[2].reload
end
specify { pages[2].menu_order.should == 1 }
it "should remove the excluded css class from the pages control" do
page.should_not have_selector "li.excluded#page_#{pages[2].id}"
end
end
兩個描述與expected css "..." (not) to return (any|some)thing
斷言的CSS(每個塊的第二個例子),當塊失敗。
這是click_link行動的控制器代碼:
def exclude_page
page = Page.find params[:page_id]
Hierarchy::PageHierarchy.exclude! page
redirect_to admin_pages_path
end
def include_page
page = Page.find params[:page_id]
Hierarchy::PageHierarchy.include! page
redirect_to admin_pages_path
end
這些方法排除模塊!和包括!:
def self.exclude! page
page.update_attribute :menu_order, -1
end
def self.include! page
page.update_attribute :menu_order, 1
menu_order = 2
page.siblings.each do |p|
p.update_attribute :menu_order, menu_order unless p.menu_order == -1
menu_order += 1
end
end
這是重定向(admin_pages_path
)的目標的控制器的代碼:
def index
@pages = Page.roots
end
凡Page.roots是where parent_id: nil
一個範圍。
第一個例子塊是容易修復。我只需要重新瀏覽頁面和CSS匹配。但afaik Capybara應該遵循重定向。那麼爲什麼我必須重新訪問?
第二塊是比較困難的(只是打我,如果這是值得它自己的問題,我只是想避免doubleposting所有代碼。)
重溫頁面將無法勝任這個時候。事實上再訪似乎改變數據庫:
69: end
70: pages[2].reload
71: end
72: its(:menu_order) { should == 1}
73: it "should add an excluded css class to the pages control" do
=> 74: binding.pry
75: page.should_not have_selector "li.excluded#page_#{pages[2].id}"
76: end
77: end
78: end
[1] pry(#<RSpec::Core::ExampleGroup::Nested_1::Nested_2>)> pages[2].id
=> 9
[2] ... > Page.find(9).menu_order
=> 1
[3] ... > visit admin_pages_path
=> nil
[4] ... > Page.find(9).menu_order
=> -1
這是我弄糊塗了點。所以我不明白的是: - 爲什麼我必須重新訪問第一個示例塊? - 爲什麼這個技巧在第二個示例塊中不起作用? - 爲什麼要重新訪問更改數據庫的頁面?
請注意,所有這些僅適用於水豚/ RSpec。當使用瀏覽器手動執行此操作時,一切正常。
UPDATE:頁
定義:
let(:pages) { bunch_of_pages.sort { |a, b| a.menu_order <=> b.menu_order } }
# bunch_of_pages:
def bunch_of_pages
pages = []
roots << root1 = FactoryGirl.create(:public_page, menu_order: (rand*1000).to_i)
child1 = FactoryGirl.create :public_page, parent: root1, menu_order: (rand*1000).to_i
child2 = FactoryGirl.create :public_page, parent: root1, menu_order: (rand*1000).to_i
subchild1 = FactoryGirl.create :public_page, parent: child2, menu_order: (rand*1000).to_i
pages << root2 = FactoryGirl.create(:public_page, menu_order: (rand*1000).to_i)
child3 = FactoryGirl.create :public_page, parent: root2, menu_order: (rand*1000).to_i
.
.
.
pages
end
這隻有很少做第二規範的問題。看看這個例子。在重新訪問admin_pages_path後,數據庫以某種方式更改。這發生在should或should_not被調用之前。如果我使用'should have_no_selector'而不是'should_not have_selector',那麼代碼的bevaviour不會改變。 沒有異步性,所以這實際上無關緊要。 – ohcibi 2012-07-30 21:56:26
你是對的,它不應該影響測試失敗的原因。兩個問題:1)「頁面」的定義是什麼?它使用'let!'嗎? 2)你是否在使用db清理器的事務或截斷? – 2012-07-31 03:48:18
1)我已經更新了代碼 的問題2)我猜rspec正在執行事務中的每個示例,但我沒有對此做任何明確的描述。只需要默認rspec配置。 – ohcibi 2012-07-31 09:20:31