我只是学习用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
答案 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
(注意:上面修正了一些拼写错误。)