这里是 M Hartl 的 Ruby on Rails 教程中的一些代码。任何人都可以解释为什么实例变量(@user)是必要的以及为什么不使用局部变量。另外,由于实例变量应该是类实例中的变量,那么 @user 是从哪个类实例化的?
require 'spec_helper'
describe User do
before { @user = User.new(name: "Example User", email: "[email protected]") }
subject { @user }
it { should respond_to(:name) }
it { should respond_to(:email) }
end
在该实例中使用局部变量意味着其范围将仅限于
before
,因此会导致错误。 @user
属于 User 类型,但它是 describe
块的实例变量。 Rspec 有一些魔力,可以在运行时从每个 describe
块中创建一个类。每个示例(it
块)最终都是该类的子类。类继承让示例可见@user
。
编辑于2017-05-14
链接的博客文章不再可用。使用 Wayback Machine 链接更新 + 在此处内联相关部分。
请注意,这被认为是反模式,如本博客文章中所述。请使用
let
来代替。
let
具有以下优点:
不能使用局部变量,因为局部变量只存在于局部方法的作用域中。
before
、subject
和 it
在同一类中生成不同的作用域。
以下代码
before { user = User.new(name: "Example User", email: "[email protected]") }
当你调用它时会引发一个未定义的变量
subject { user }
实例
@user
是类 User
的实例(毕竟,您是用 User.new
创建的)。
但是,您可能需要使用
let
命令来代替实例变量。另外,如果你定义
subject { User.new(name: "Example User", email: "[email protected]") }
不需要使用
before
。您还将获得额外的好处,获得可用于访问实例的 subject
方法,相当于定义 let(:subject)
。
subject
和 it
块位于不同的作用域下,因此局部变量不起作用。 @user
属于 RSpec 在底层生成的类。