如何设置共享示例?

时间:2016-09-21 09:44:49

标签: ruby-on-rails ruby rspec

我只是学习用ruby和rails编写规范。所以我确实有两个类似的模型在投票时表现相似:问答。所以我尝试不重复代码并为这两个代码编写共享示例。

RSpec.shared_examples_for 'User Votable' do

  let!(:user){ create :user } 
  let!(:sample_user){ create :user }   
  let!(:vote){ create :vote, user: user, votable: votable, vote_field: 1}   

  it 'user different from resource user is accapteble' do        
    expect(votable.user_voted?(sample_user)).to be_falsy
  end   

  it 'user similar to resource user is accapteble' do

    expect(votable.user_voted?(user)).to be_truthy
  end

end

测试本身

describe 'user_voted?' do 
  def votable
    subject{ build(:question)}
  end
  it_behaves_like 'User Votable'
end

此规范中的最后一个失败(我认为因为主题 - 我创建投票时不会改变) 如果我能够管理并理解如何正确地做到这一点,我将非常高兴。非常感谢任何建议

此外,当我尝试使用这样的模拟时,它抱怨没有主键

allow(:question){create :question}

Failures:

1)问题user_voted?表现得像User Votable用户类似于资源用户是可以接受的      失败/错误:期望(votable.user_voted?(用户))。to be_truthy

   expected: truthy value
        got: false
 Shared Example Group: "User Votable" called from ./spec/models/question_spec.rb:23

2 个答案:

答案 0 :(得分:1)

您可以设置votable,而不是使用subject方法:

it_behaves_like 'User Votable' do
  subject { build(:question) }
end

答案 1 :(得分:1)

您实际上不需要使用subject,您可以使用let设置您想要的任何上下文,并且它将在块中可用:

describe 'user_voted?' do 
  let(:votable) { build(:question) }
  it_behaves_like 'User Votable'
end

然后,您可以在共享示例中引用votable,它将由上下文定义:

RSpec.shared_examples_for 'User Votable' do
  let!(:user) { create :user } 
  let!(:sample_user) { create :user }   
  let!(:vote) { create :vote, user: user, votable: votable, vote_field: 1 }

  it 'user different from resource user is acceptable' do        
    expect(votable.user_voted?(sample_user)).to be_falsy
  end   

  it 'user similar to resource user is acceptable' do
    expect(votable.user_voted?(user)).to be_truthy
  end
end

您还可以偶然将参数传递到it_behaves_like块以获得更大的灵活性。

参考:Providing context to a shared group using a block

(注意:上面修正了一些拼写错误。)