Rspec让范围界定

Cos*_*sti 34 ruby rspec

我相信我有一个rspec let和范围问题.我可以在示例中使用let定义的方法("it"块),但不能在外面(我执行let的describe块).

5   describe Connection do
8     let(:connection) { described_class.new(connection_settings) }
9 
10    it_behaves_like "any connection", connection
24  end
Run Code Online (Sandbox Code Playgroud)

当我尝试运行此规范时,我收到错误:

connection_spec.rb:10:未定义的局部变量或类的方法`connection':0xae8e5b8(NameError)

如何将连接参数传递给it_behaves_like?

Ho-*_*iao 27

let()应该限定为示例块,并且在其他地方不可用.实际上并没有使用let()作为参数.它不能用it_behaves_like作为参数的原因与let()的定义方式有关.Rspec中的每个示例组都定义了一个自定义类.let()定义该类中的实例方法.但是,当您在该自定义类中调用it_behaves_like时,它将在类级别而不是在实例中调用.

我像这样使用了let():

shared_examples_for 'any connection' do
  it 'should have valid connection' do
    connection.valid?
  end
end

describe Connection do
  let(:connection) { Connection.new(settings) }
  let(:settings) { { :blah => :foo } }
  it_behaves_like 'any connection'
end
Run Code Online (Sandbox Code Playgroud)

我做过类似于bcobb的回答,但我很少使用shared_examples:

module SpecHelpers
  module Connection
    extend ActiveSupport::Concern

    included do
      let(:connection) { raise "You must override 'connection'" }
    end

    module ClassMethods
      def expects_valid_connection
        it "should be a valid connection" do
          connection.should be_valid
        end
      end
    end
  end
end

describe Connection do
  include SpecHelpers::Connection

  let(:connection) { Connection.new }

  expects_valid_connection
end
Run Code Online (Sandbox Code Playgroud)

这些共享示例的定义比使用共享示例更加冗长.我想我发现"it_behave_like"比直接扩展Rspec更尴尬.

显然,您可以为.expects_valid_connections添加参数

我写这篇文章是为了帮助朋友的rspec课程:http://ruby-lambda.blogspot.com/2011/02/agile-rspec-with-let.html ...


bco*_*obb 20

编辑 - 对我的第一个解决方案完全嗤之以鼻.郝昊生对原因作了很好的解释.

您可以it_behaves_like像这样给出一个块:

describe Connection do
  it_behaves_like "any connection" do
    let(:connection) { described_class.new(connection_settings) }
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止更好的答案. (5认同)
  • 这个!好答案 (2认同)

小智 6

我发现如果你没有显式传递声明的参数let,它将在共享示例中可用.

所以:

describe Connection do
  let(:connection) { described_class.new(connection_settings) }

  it_behaves_like "any connection"
end
Run Code Online (Sandbox Code Playgroud)

连接将在共享示例规范中提供


Cos*_*sti 3

我找到了对我有用的东西:

   describe Connection do
     it_behaves_like "any connection", new.connection
     # new.connection: because we're in the class context 
     # and let creates method in the instance context, 
     # instantiate a instance of whatever we're in
   end
Run Code Online (Sandbox Code Playgroud)