RSpec变量范围

时间:2016-04-20 16:25:40

标签: ruby rspec sinatra sequel

我在访问rspec测试中的全局可用@db变量时遇到了困难。 @db变量在app中设置,该变量包含在spec_helper中。

以下代码:

require File.expand_path '../../spec_helper.rb', __FILE__


p @db
describe MyModel do
  before do
    p @db
  end
  context 'constraints' do
    it 'is expected to do something' do
      p @db
    end
  end
end

当我运行它时,我得到输出:

#<Sequel::Mysql2::Database: "mysql2://root:@localhost/my_project">
nil
nil

表示@db变量在rspec测试之外正确设置,但在测试运行后无法访问。如何从我的测试中访问@db

2 个答案:

答案 0 :(得分:1)

@ sigil开头的变量是实例变量。它们属于特定的对象(即实例),并且只能从该对象访问。它们总是相对于self查找。

在您的情况下,您有两个不同对象的两个实例变量。

在第4行,self是所谓的main顶级对象。在第7行和第11行,self是类RSpec::ExampleGroups::MyModel::Constraints的一个实例,它是一个完全不同的类的完全不同的对象,具有完全不同的实例变量集。

如果真的需要访问那个特定的实例变量,你可以这样做:

$main = self

require File.expand_path '../../spec_helper.rb', __FILE__


p @db
describe MyModel do
  before do
    p $main.instance_variable_get(:@db)
  end
  context 'constraints' do
    it 'is expected to do something' do
      p $main.instance_variable_get(:@db)
    end
  end
end

但最简单的解决方案是在before挂钩中的正确的对象上设置实例变量。

答案 1 :(得分:0)

我不确定你的spec_helper.rb中有什么,但你应该包括这个:

RSpec.configure do |config|
  config.before(:each) do
    @db = 'your db object'
  end
end

这与在测试示例正上方挂钩之前的定义相同,除了它将在每次测试之前全局运行。