检查RSpec中的ActiveRecord关联
我正在学习如何使用Rspec编写测试用例。 我有一个简单的post评论脚手架,其中一个post可以有很多评论。 我正在使用Rspec进行测试。 我应该如何检查Post :has_many :comments
。 我应该将Post.comments
方法存根,然后通过返回注释对象数组的模拟对象来检查它吗? 真的需要测试AR协会吗?
由于ActiveRecord关联应该由Rails测试套件(它们是)进行良好测试,因此大多数人并不认为有必要确保它们正常工作 – 它只是假设它们会。
如果你想确保你的模型正在使用那些关联,那就是不同的东西,而你想要测试它并没有错。 我喜欢使用shoulda gem这样做。 它可以让你做这样的事情:
describe Post do it { should have_many(:comments).dependent(:destroy) } end
测试协会通常是一种良好的做法,特别是在TDD受到高度重视的环境中 – 其他开发人员在查看相应的代码之前通常会查看您的规范。 测试关联可确保您的spec文件最准确地反映您的代码。
您可以通过两种方式测试关联:
-
使用FactoryGirl:
expect { FactoryGirl.create(:post).comments }.to_not raise_error
这是一个相对肤浅的测试,将与工厂一样:
factory :post do title { "Top 10 Reasons why Antelope are Nosy Creatures" } end
如果您的模型缺少与注释的
has_many
关联,则返回NoMethodError。 -
您可以使用ActiveRecord #reflect_on_association方法更深入地了解您的关联。 例如,通过更复杂的关联:
class Post has_many :comments, through: :user_comments, source: :commentary end
您可以深入了解您的关联:
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
并测试相关的任何选项或条件。
如果您不想使用像shoulda这样的外部gem来测试您的关联(请参阅Robert Speicher的答案以获取详细信息),另一个选择是使用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
大多数人不测试关联,因为Rails已经进行了unit testing以确保这些方法正常工作。 如果你正在做一些复杂的事情,比如涉及proc或其他东西,你可能想要明确地测试它。 通常你可以这样做
a = Post.new a.comments << Comment.new assert a.save assert a.comments.size == 1
或类似的东西。