RSpec: 在使用 `subject` 时,我必须将对象分配给 @variable 才能使其持久化?

RSpec: when using `subject`, I have to assign an object to an @variable to make it persist?

application_helper.rb有以下小帮手:

def container_for(object, options = {})
  tag = options[:tag] || 'div'

  content_tag tag, id: dom_id(@user), class: dom_class(@user) do
    yield
  end
end

我想这样测试:

describe '#container_for(object)' do
  subject { container_for(create(:user)) { 'Some content' } }

  it { should have_css 'div#user_1.user' }
end

但这会导致以下错误:

1) ApplicationHelper#container_for(object) 
   Failure/Error: subject { container_for(create(:user)) { 'Some content' } }
   NoMethodError:
     undefined method `to_key' for nil:NilClass
   # /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/actionview-4.2.0/lib/action_view/record_identifier.rb:80:in `record_key_for_dom_id'
   # /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/actionview-4.2.0/lib/action_view/record_identifier.rb:62:in `dom_id'
   # ./app/helpers/application_helper.rb:65:in `container_for'
   # ./spec/helpers/application_helper_spec.rb:18:in `block (3 levels) in <top (required)>'
   # ./spec/helpers/application_helper_spec.rb:20:in `block (3 levels) in <top (required)>'

当我将创建的用户分配给 @variable 时,它起作用了:

describe '#container_for(object)' do
  subject { container_for(@user = create(:user)) { 'Some content' } }

  it { should have_css 'div#user_1.user' }
end

这是为什么?

因为在第一种情况下,您的 @user 助手内的实例变量未初始化,即等于 nil,但在第二种情况下,您将 User 对象的实例分配给它。

所以,你的 container_for 有副作用。它期望 @user 之前已经初始化。