我正在学习rspec,我不得不注意到我的代码中有很多重复。以下只是其他许多例子中的两个。有没有一种方法可以创建一个共享测试,而不必遍历每个单独的属性?
describe "validation" do
describe "user_id" do
it "should not be blank or nil" do
@comment.user_id = nil
@comment.should_not be_valid
@comment.user_id = " "
@comment.should_not be_valid
end
it "should an integer" do
@comment.user_id = "a"
@comment.should_not be_valid
end
end
describe "post_id" do
it "should not be blank or nil" do
@comment.post_id = nil
@comment.should_not be_valid
@comment.post_id = " "
@comment.should_not be_valid
end
it "should an integer" do
@comment.post_id = "a"
@comment.should_not be_valid
end
end
end
最佳答案
在第一个describe
块中,您可以将主题设置为@comment.user_id
,如下所示:
describe "validation" do
describe "user_id" do
before { @comment = Comment.create } # or however you want to initialize your comment
# (FactoryGirl is commonly used)
subject { @comment.user_id }
it "should not be blank or nil" do
before { @comment.user_id = nil } #I edited this to make it clearer.
it { should_not be_valid }
before { @comment.user_id = " " }
it { should_not be_valid }
end
...
这会使它变干一些,让它更容易阅读。很明显你可以把我这里剩下的画出来。
编辑:这不会保存很多字符(实际上您在最后键入的字符更多),但它确实消除了spec文件本身中
@comment.{attrbute} = whatever
的重复。可以为每个分配定义一个助手,如下所示:/spec/helpers/comment_spec_helper.rb
def user_id nil
@comment.user_id = nil
end
....
对每个属性都这么做。那么在你的规范中:
subject { @comment.user_id }
it "should not be blank" do
before { user_id nil }
it { should_not be_valid }
it "should not be nil" do
...
缺点是,对于helper中的每个属性,都必须这样做,最后还要做一些工作。但是,如果您主要关心的是消除spec文件中的重复,这将有所帮助。
我不知道这是多么地道。我通常在spec文件中启动新的对象进行验证测试(spec_helper通常处理多个步骤的过程,比如单击下拉菜单、填写文本,然后单击“提交”),但可能您的验证比我通常的要多。
更新
我正在做一个项目,只是翻阅了我参加的代码学校rspec课程的笔记,我想我会建议大家分享一些例子。他们举的例子是:
describe Zombie do
it_behaves_like ‘the undead’, Zombie.new
end
describe Vampire do
it_behaves_like ‘the undead’, Vampire.new
end
shared_examples_for ‘the undead’ do |undead|
it ‘does not have a pulse’ do
undead.pulse.should == false
end
end
这似乎是适用的,不过您必须记住一定要conventions以确保加载共享示例。
这真的会让你的代码干涸,但我个人会有点担心可读性。我想如果你用一个足够描述性的名字来描述你的共享示例,你会没事的。
关于ruby-on-rails - 如何使Rails的RSpec测试干燥,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15773874/