我正在学习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
答案 0 :(得分:5)
您可以尝试:https://github.com/thoughtbot/shoulda-matchers
它为您的模型提供了许多简单的匹配器
答案 1 :(得分:3)
在第一个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
...
缺点是,你必须为助手中的每个属性做到这一点,最后你还要做更多的工作。但如果您主要关注的是消除spec文件中的重复,这将有所帮助。
我不知道这是多么惯用。我通常在spec文件中启动新对象以进行验证测试,(我的spec_helper通常会处理多步骤过程,例如单击下拉菜单,填写文本,然后单击“提交”),但也许你有比我通常更多的验证。
更新
我正在研究一个项目,刚刚翻过我所参加的Codeschool的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以确保加载了共享示例。
这会真的干掉你的代码,但我个人会对可读性有点担心。我想如果你为共享的例子使用一个描述性足够的名字,你就可以了。
答案 2 :(得分:1)
您可以使用工厂(例如FactoryGirl):
build(:comment, user_id: nil).should_not be_valid