rspec shared_examples不能嵌套

时间:2013-12-02 07:25:41

标签: ruby-on-rails rspec

我想编写两个测试,并且两者都部分依赖于相同的行为,大致如下所示。这是我想从我的代码中提取的东西,似乎共享上下文是如何做到的,但是存在一个范围问题。

require 'spec_helper'
def getlink()
  ['link','id']
end
describe 'static pages' do
  hash = {'link' => {'id' => 'payload'},'link_' => {'id_' => 'payload_'}}
  subject{hash}
  shared_examples_for 'it is mapped correctly' do |link, id|
    it 'is mapped correctly' do
      expect(subject[link]).to have_key(id)
    end
  end
  describe 'the payload is correct' do
    it_should_behave_like 'it is mapped correctly', 'link','id'
    it 'has the correct value' do
      expect(subject['link']['id']).to eq('payload')
    end
  end
  # works fine
  describe 'the get link function works correctly' do
    it 'links inside the has' do
      link = getlink()
      expect(subject[link[0]]).to have_key(link[1])
    end
  end
  # fails saying that it_should_behave_like is not defined.
  describe 'the get link function works correctly with shared examples' do
    it 'links inside the has' do
      link = getlink()
      it_should_behave_like 'it is mapped correctly', link[0], link[1]
    end
  end
end

为什么这个设计失败了?有没有惯用的方法来实现这一目标?

1 个答案:

答案 0 :(得分:0)

与其他it方法一样,it_should_behave_like未在其他it方法中定义。您可以看到在嵌套常规it s:

时遇到相同的异常
require 'rspec/autorun'
describe 'it inside it' do
  it 'outer' do
    it 'inner' do
    end
  end
end
#=>  1) it inside it outer
#=>     Failure/Error: Unable to find matching line from backtrace
#=>     NoMethodError:
#=>       undefined method `it' for #<RSpec::Core::ExampleGroup::Nested_1:0x28e1e60>
#=>     # stuff.rb:37:in `block (2 levels) in <main>'

要修复异常,您可以简单地删除外部it

describe 'the get link function works correctly with shared examples' do
  link = getlink()
  it_should_behave_like 'it is mapped correctly', link[0], link[1]
end

如果外部it用于描述某些信息,则可以改为context

describe 'the get link function works correctly with shared examples' do
  context 'links inside the has' do
    link = getlink()
    it_should_behave_like 'it is mapped correctly', link[0], link[1]
  end
end