RSpec 变量范围



我在 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

@符号开头的变量是实例变量。它们属于特定对象(即实例),只能从该对象访问。它们总是相对于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 钩子中的正确对象上设置实例变量。

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

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

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

最新更新