【问题标题】:RSpec Variable ScopingRSpec 变量范围
【发布时间】:2016-08-13 11:40:44
【问题描述】:

在我的 rspec 测试中访问全局可用的 @db 变量时遇到困难。 @db 变量在通过 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

【问题讨论】:

    标签: ruby rspec sinatra sequel


    【解决方案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 挂钩中的 正确 对象上设置实例变量。

    【讨论】:

    【解决方案2】:

    我不确定您的 spec_helper.rb 中有什么,但您应该包含以下内容:

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

    这与直接在测试示例上方定义 before 钩子相同,只是它将在每次测试之前全局运行。

    【讨论】:

    • 您还可以在设置全局规则时指定过滤器,更多信息请参见此线程:stackoverflow.com/questions/29094646/…
    • 我试过没有成功。我仍然为@db 获得nil。我做了@db = database 没有成功。
    猜你喜欢
    • 1970-01-01
    • 2011-10-10
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 2014-01-31
    相关资源
    最近更新 更多