Checking ActiveRecord Associations in RSpec

前端 未结 4 1380
长情又很酷
长情又很酷 2021-02-05 10:16

I am learning how to write test cases using Rspec. I have a simple Post Comments Scaffold where a Post can have many Comments. I am testing this using Rspec. How should i go abo

相关标签:
4条回答
  • 2021-02-05 10:34

    Since ActiveRecord associations should be well-tested by the Rails test suite (and they are), most people don't feel the need to make sure they work -- it's just assumed that they will.

    If you want to make sure that your model is using those associations, that's something different, and you're not wrong for wanting to test that. I like to do this using the shoulda gem. It lets you do neat things like this:

    describe Post do
      it { should have_many(:comments).dependent(:destroy) }
    end
    
    0 讨论(0)
  • 2021-02-05 10:34

    Testing associations is good practice generally, especially in an environment where TDD is highly regarded- other developers will often look to your specs before looking at the corresponding code. Testing associations makes sure that your spec file most accurately reflects your code.

    Two ways you can test associations:

    1. With FactoryGirl:

      expect { FactoryGirl.create(:post).comments }.to_not raise_error
      

      This is a relatively superficial test that will, with a factory like:

      factory :post do
        title { "Top 10 Reasons why Antelope are Nosy Creatures" }
      end
      

      return you a NoMethodError if your model lacks a has_many association with comments.

    2. You can use the ActiveRecord #reflect_on_association method to take a more in-depth look at your association. For instance, with a more complex association:

      class Post
        has_many :comments, through: :user_comments, source: :commentary
      end
      

      You can take a deeper look into your association:

      reflection = Post.reflect_on_association(:comment)
      reflection.macro.should eq :has_many
      reflection.options[:through].should eq :user_comments
      reflection.options[:source].should eq :commentary
      

      and test on whatever options or conditions are relevant.

    0 讨论(0)
  • 2021-02-05 10:36

    Most people don't test the associations, as Rails already has unit tests to make sure those methods work correctly. If you are doing something complex, like involving a proc or something, you might want to explicitly test it. Usually you can do this by just doing

    a = Post.new
    a.comments << Comment.new
    assert a.save
    assert a.comments.size == 1
    

    or something akin to that.

    0 讨论(0)
  • 2021-02-05 10:49

    If you'd rather not use an external gem like shoulda to test your associations (see Robert Speicher's Answer for details on that), another option is to use reflect_on_association to get the AssociationReflection object for the relevant association, and then assert on that:

    describe Post do
      it "should destroy its comments when it is destroyed" do
        association = Post.reflect_on_association(:comments)
    
        expect(association).to_not be_nil
        expect(association.options[:dependent]).to eq :destroy
      end
    end
    
    0 讨论(0)
提交回复
热议问题