1

どういうわけか関連しているように見える 2 つの失敗した仕様があります。ここにそれらがあります:

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

css (各ブロックの 2 番目の例) を でアサートすると、両方の記述ブロックが失敗しexpected css "..." (not) to return (any|some)thingます。

これは、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 が一致します。しかし、私の知る限り、カピバラはリダイレクトに従うだけです。では、なぜ再訪する必要があるのでしょうか。

2 番目のブロックはより難しいです (これが独自の質問に値する場合は、私を殴ってください。すべてのコードを二重投稿するのを避けたかっただけです)。

このページに再度アクセスしても、今回はうまくいきません。実際、再訪するとデータベースが変更されるようです:

    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

ここが迷うポイントです。だから私が理解していないのは: - 最初の例のブロックで再訪する必要があるのはなぜですか? - このトリックが 2 番目のサンプル ブロックで機能しないのはなぜですか? - ページを再訪問するとデータベースが変更されるのはなぜですか?

これはすべて 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
4

1 に答える 1

0

ページをリロードしないとテストに合格しない理由がわかりません。ただし、2 番目の例の正しい書き方は次のとおりです。

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

Capybara のアサーションには、失敗する前に特定の回数一致を再試行するメカニズムが組み込まれています。shouldを使用しない場合にのみ機能しますshould_not

于 2012-07-29T07:44:46.320 に答える