2012-07-28 18 views
1

我有兩個失敗的規範,似乎是某種聯繫。下面是它們:水豚不遵循重定向和修改數據庫

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 

回答

0

不知道爲什麼你的測試不及格而無需重新加載頁面。然而,寫第二個例子中,正確的方法是:

page.should have_no_selector "li.excluded#page_#{pages[2].id}" 

水豚的說法有一個內置的機制來重新嘗試匹配的特定次數,他們失敗了。它只適用於使用should而不是should_not

+0

這隻有很少做第二規範的問題。看看這個例子。在重新訪問admin_pages_path後,數據庫以某種方式更改。這發生在should或should_not被調用之前。如果我使用'should have_no_selector'而不是'should_not have_selector',那麼代碼的bevaviour不會改變。 沒有異步性,所以這實際上無關緊要。 – ohcibi 2012-07-30 21:56:26

+0

你是對的,它不應該影響測試失敗的原因。兩個問題:1)「頁面」的定義是什麼?它使用'let!'嗎? 2)你是否在使用db清理器的事務或截斷? – 2012-07-31 03:48:18

+0

1)我已經更新了代碼 的問題2)我猜rspec正在執行事務中的每個示例,但我沒有對此做任何明確的描述。只需要默認rspec配置。 – ohcibi 2012-07-31 09:20:31