ヨージとプログラミング

プログラミング勉強の記録

【Rails】RSpec(Capybara)で使うvisitはit句の中でしか使えない?(調査中)

調べ中ですが忘れないようにとりあえずメモ

system specでよく使うvisit

system specを書く時、僕なんかはログイン状態のテストをするときは

visit login_path

みたいに書いて、ログインページに移動するんですが。何気なく使っていると以下のようなエラーが出ました。

> docker-compose run web rspec

An error occurred while loading ./spec/system/records_spec.rb.
Failure/Error: visit login_path

NameError:
  undefined local variable or method `login_path' for RSpec::ExampleGroups::Nested::Nested::Nested:Class

0 examples, 0 failures, 1 error occurred outside of examples

login_pathみたいなものは定義されてないよということですが、要は、visit句が機能してないということ。
ちなみにコードはこうです。(分かりやすくしています)

describe 'レコード', type: :system do
  context 'ログインしている時' do
    let(:user) { FactoryBot.create(:user) } # user作成
    visit login_path # ログインページへ
    fill_in "email-form", with: user.eamil

    it 'hogehoge' do       
      expect(page).to have_css('#record')
    end
  end
end

そこで試しに、visit句を含めたフィクスチャをit句の中へ

describe 'レコード', type: :system do
  context 'ログインしている時' do
    it 'hogehoge' do       
      let(:user) { FactoryBot.create(:user) } # user作成
      visit login_path # ログインページへ
      fill_in "email-form", with: user.eamil

      expect(page).to have_css('#record')
    end
  end
end

すると、エラーなくRSpecが動きました。

visit ○○_pathはit句の中でしか使えないのか?

軽くしか調べてないのでなんとも言えませんが 少なくともcontext直下では使えないっぽいですね。

(追記)
とりあえずこんな感じで運用中

describe 'レコード', type: :system do
  context 'ログインしている時' do
    let(:user) { FactoryBot.create(:user) } # user作成

    before do
      visit login_path # ログインページへ
      fill_in "email-form", with: user.eamil
    end

    it 'hogehoge' do       
      expect(page).to have_css('#record')
    end
  end
end

流石にフィクスチャをit句の中に入れるのは抵抗があるので、beforeブロックにしました。ポイントはlet句はbeforeの外に出しています。letはbeforeの中で使えないので