【问题标题】:How to include shared examples without subject如何包含没有主题的共享示例
【发布时间】:2013-12-28 01:00:52
【问题描述】:

我正在使用 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

在访问带有路线名称的页面和点击访问它们时,我正在检查相同的内容。我想重构它。

【问题讨论】:

    标签: ruby rspec capybara


    【解决方案1】:

    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
    

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

    如果您愿意将最后的连续示例分解为一系列独立示例,那么您可以在这两个示例中使用共享示例。尽管如此,我知道共享该代码的唯一方法是通过同一字符串的eval

    【讨论】:

    • 我的意思是click_link之后必须改变主题,不是吗?但我不想明确地这样做并且想使用expect(page).to 而不是使用主题。
    • 不,subjectclick_link 之后不会更改,但独立于此,您可以在共享示例中使用 expect(page).to ... 并依靠在 rspec 上下文中评估 page它被称为。
    • 问题是如何在expect(page).to 上调用it_should_behave_likeexpect(page).to it_should_behave_like 不起作用
    • 对不起,我还是不清楚你在问什么。假设expect 调用将在共享示例中。
    • 我想打电话给expect(page).to it_should_behave_like 'something',但是打不通。我需要像it_should_behave_like 这样的方法,它可以与expect(page).to 一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 2020-06-06
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多