我有两个失败的规格,似乎有点相关。他们是:
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应该遵循重定向。那为什么我要重新访问?
第二个块更难(如果这值得自己提出问题,请打我,我只是想避免重复使用所有代码。)
这次重新访问页面不会有效。事实上,重新访问似乎改变了数据库:
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
这是我感到困惑的地方。所以我不明白的是: - 为什么我必须在第一个示例块中重新访问? - 为什么这个技巧在第二个示例块中不起作用? - 为什么要重新访问更改数据库的页面?
请注意,所有这些仅适用于Capybara / RSpec。使用浏览器手动执行此操作时,一切正常。
更新:
页面定义:
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
答案 0 :(得分:0)
不确定为什么在没有重新加载页面的情况下测试没有通过。但是,编写第二个示例的正确方法是:
page.should have_no_selector "li.excluded#page_#{pages[2].id}"
Capybara的断言有一个内置机制,可以在失败前重试一次特定次数的匹配。它仅在您使用should
而非should_not
时才有效。