我正在使用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
我在访问带有路由名称的页面时以及访问它们时单击时检查相同的内容。我想重构它。
答案 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
。