检查 RSpec 中的 ActiveRecord 关联

发布于 2024-08-29 16:09:37 字数 199 浏览 5 评论 0原文

我正在学习如何使用 Rspec 编写测试用例。我有一个简单的帖子评论支架,其中一个帖子可以有很多评论。我正在使用 Rspec 对此进行测试。我应该如何检查 Post :has_many :comments。我应该存根 Post.comments 方法,然后通过返回评论对象数组的模拟对象来检查它吗?真的需要对 AR 关联进行测试吗?

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 about checking for Post :has_many :comments. Should I stub Post.comments method and then check this with by returning a mock object of array of comment objects? Is testing for AR associations really required ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔一刀 2024-09-05 16:09:37

由于 ActiveRecord 关联应该经过 Rails 测试套件的充分测试(而且确实如此),因此大多数人并不觉得有必要确保它们能够正常工作——只是假设它们会正常工作。

如果您想确保您的模型使用这些关联,那就是不同的事情,并且您想要测试这一点并没有错。我喜欢使用 shoulda gem 来完成此操作。它可以让你做这样的巧妙的事情:

describe Post do
  it { should have_many(:comments).dependent(:destroy) }
end

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
我不吻晚风 2024-09-05 16:09:37

一般来说,测试关联是一种很好的做法,尤其是在 TDD 受到高度重视的环境中——其他开发人员通常会在查看相应的代码之前先查看您的规范。测试关联可确保您的规范文件最准确地反映您的代码。

测试关联的两种方法:

  1. 使用 FactoryGirl:

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

    这是一个相对肤浅的测试,使用这样的工厂:

    工厂:post do
      title {“羚羊是爱管闲事的动物的十大原因”}
    结尾
    

    如果您的模型缺少与注释的 has_many 关联,则返回 NoMethodError。

  2. 您可以使用 ActiveRecord #reflect_on_association 更深入地了解您的协会的方法。例如,具有更复杂的关联:

    类帖子
      has_many :comments,通过: :user_comments,来源: :commentary
    结尾
    

    您可以更深入地了解您的协会:

    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
    

    并测试相关的任何选项或条件。

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.

森林很绿却致人迷途 2024-09-05 16:09:37

如果您不想使用 shoulda 之类的外部 gem 来测试您的关联(请参阅罗伯特·斯派克答案 有关详细信息),另一种选择是使用 reflect_on_association 获取相关关联的 AssociationReflection 对象,然后对其进行断言:

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

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
枯叶蝶 2024-09-05 16:09:37

大多数人不会测试关联,因为 Rails 已经有单元测试来确保这些方法正常工作。如果您正在做一些复杂的事情,例如涉及过程或其他东西,您可能需要显式地测试它。通常你可以通过做

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

或类似的事情来做到这一点。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文