tkymtk's blog

Ruby on Rails及びその周辺について調べたこと。Do whatever you want to do at your own pace.

RSpec: カスタムマッチャ Rails Tutorialでハマったところ。should_notの動作

問題

  • should_notが期待通りに動作しない

カスタムマッチャの定義

RSpec::Matchers.define :have_error_message do |message|
  match do |page|
    expect(page).to have_selector('div.alert.alert-error', text: message)
  end

Spec

describe "with invalid information" do
  before { click_button "Sign in" }

  it { should have_title('Sign in') }
  it { should have_error_message('Invalid') }

  describe "after visiting another page" do
    before { click_link "Home" } 
#  このshould_notの効果がない。shouldと同じ動作をしてしまう。 
    it { should_not have_error_message('Invalid') }
  end
end

エラー

1) Authentication sign in page with invalid information after visiting another page 
     Failure/Error: it { should_not have_error_message('Invalid') }
     Capybara::ExpectationNotMet:
       expected to find css "div.alert.alert-danger" with text "Invalid" but there were no matches
     # ./spec/support/utilities.rb:7:in `block (2 levels) in <top (required)>'
     # ./spec/features/authentication_pages_spec.rb:21:in `block (5 levels) in <top (required)>'

解決策

カスタムマッチャの定義を変更

RSpec::Matchers.define :have_error_message do |message|
  match do |page|
    page.has_selector?('div.alert.alert-error', text: message)
  end
end

これでちゃんと期待通りの動作するようになった。

その他注意点

  • Sporkを起動しながらテストをしている場合は、逐次環境を読み込み直さないと変更が反映されないので注意。(Sporkと連動している場合、Guardの起動時も。)
  • コードはあっているのにテストは失敗し続けるということが起きる。
  • そのため、時間はかかるが、この場合GuardやSporkを切ってテストを実行する方がよい。

関連リンク

参考:

Rails Tutorial:

日本語版:

間違いがあれば、ご指摘下さると幸いです。