2

我正在学习 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
4

3 回答 3

5

你可以试试这个:https ://github.com/thoughtbot/shoulda-matchers

它为您的模型提供了许多简单的匹配器

于 2013-04-02T20:37:50.073 回答
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
    ...

我认为这会使它变干一些并使其更具可读性。显然,您可以将其余部分从我这里的内容中提取出来。


编辑:这不会保存很多字符(实际上你最后会输入更多),但它确实消除了@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_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

这似乎适用,但您必须牢记某些约定以确保加载您的共享示例。

这真的会让你的代码变干,但我个人会有点担心可读性。我想如果你为你的共享示例使用一个足够描述性的名称,你会没事的。

于 2013-04-03T00:28:42.823 回答
1

您可以使用工厂(例如 FactoryGirl):

build(:comment, user_id: nil).should_not be_valid
于 2013-04-03T00:03:49.627 回答