如何包含没有主题的共享示例

时间:2013-12-26 15:10:24

标签: ruby rspec capybara

我正在使用RSpec和Capybara。我想使用click_link测试导航面板,并为具体页面提供共享示例。但我不能使用it_should_behave_like,因为我不想在点击链接后更改主题。有没有办法在expect(page).to中包含一个共享示例?

编辑: 这是我的代码:

require 'spec_helper'

describe "SomeController" do

  subject { page }

  content_list = {
      home: 'Some text on the home page',
      about: 'Some text on the about page',
      order: 'Some text on the order page'
  }

  shared_examples_for 'with layout' do
    it { should have_content 'Some text on the layout' }
    it { should have_title 'Title' }
  end

  describe 'Home page' do
    before { visit root_path }
    it_should_behave_like 'with layout'
    it { should have_content content_list[:home] }
  end

  describe 'About page' do
    before { visit about_path }
    it_should_behave_like 'with layout'
    it { should have_content content_list[:about] }
  end

  describe 'Order page' do
    before { visit order_path }
    it_should_behave_like 'with layout'
    it { should have_content content_list[:order] }
  end

  it 'should have correct links on the layout' do
    visit root_path
    click_link 'Some link text'
    expect(page).to have_content content_list[:about]
    find('.logoLink').click
    expect(page).to have_content content_list[:home]
    click_link 'Another link text'
    expect(page).to have_content content_list[:about]
    click_link 'One more link text'
    expect(page).to have_content content_list[:order]
  end
end

我在访问带有路由名称的页面时以及访问它们时单击时检查相同的内容。我想重构它。

1 个答案:

答案 0 :(得分:0)

it_should_behave_like并未隐含地更改主题,因此您本身不应该有任何问题。

例如,以下过程:

shared_examples "so" do
  it "should have access to variables from calling rspec scope" do
    expect(subject).to eql("foo")
    expect(page).to eql("bar")
  end
end

describe "so test" do
  let(:subject) {"foo"}
  let(:page) {"bar"}
  it_should_behave_like "so"
end

鉴于您共享的代码,可以通过将参数传递给您拥有的共享示例并为每个页面的内容引入变量来减少一些重复。您还可以使用lambda函数来减少最后的大型顺序示例中的重复。这些技术如下所示(未经测试):

require 'spec_helper'

describe "SomeController" do

  subject { page }

  content_list = {
      home: 'Some text on the home page',
      about: 'Some text on the about page',
      order: 'Some text on the order page'
  }

  home_content = content_list[:home]
  about_content = content_list[:about]
  order_content = content_list[:order]

  shared_examples_for 'with layout' do |content|
    it { should have_content 'Some text on the layout' }
    it { should have_title 'Title' }
    it { should have_content content }
  end

  describe 'Home page' do
    before { visit root_path }
    it_should_behave_like 'with layout', home_content
  end

  describe 'About page' do
    before { visit about_path }
    it_should_behave_like 'with layout', about_content
  end

  describe 'Order page' do
    before { visit order_path }
    it_should_behave_like 'with layout', order_content
  end

  it 'should have correct links on the layout' do
    click_and_expect = lambda do |link_text, content|
      click_link link_text
      expect(page).to have_content content
    end
    visit root_path
    click_and_expect['Some link text', about_content]
    find('.logoLink').click
    expect(page).to have_content home_content
    click_and_expect['Another link text', about_content]
    click_and_expect['One more link text', order_content]
  end
end

但是,为了回复您的一条评论,我不知道如何轻松消除共享示例中的should have_content content与最终示例中的expect(page).to have_content content之间的概念重复。您可以使用后面的代码替换以前的代码,因为在这两种情况下都定义了page,但这仍然会让您重复该字符串。

如果您愿意将最后的顺序示例分解为一系列独立示例,那么您可以在两者之间使用共享示例。但是,我知道分享该代码的唯一方法是通过相同字符串的eval