Rails RSpec 测试 has_many :through 关系
Posted
技术标签:
【中文标题】Rails RSpec 测试 has_many :through 关系【英文标题】:Rails RSpec Tests for a has_many :through Relationship 【发布时间】:2011-04-27 18:55:07 【问题描述】:我是测试和 Rails 的新手,但我正试图让我的 TDD 流程正常运行。
我想知道您是否使用任何范式来测试 has_many :through 关系? (或者我想一般只是 has_many)。
例如,我发现在我的模型规范中,我肯定会编写简单的测试来检查关系的两端是否有相关方法。
即:
require 'spec_helper'
describe Post do
before(:each) do
@attr = :subject => "f00 Post Subject", :content => "8ar Post Body Content"
end
describe "validations" do
...
end
describe "categorized posts" do
before(:each) do
@post = Post.create!(@attr)
end
it "should have a categories method" do
@post.should respond_to(:categories)
end
end
end
然后在我的类别规范中我进行反向测试并检查@category.posts
我还缺少什么?谢谢!!
【问题讨论】:
【参考方案1】:我建议查看名为 Shoulda 的 gem。它有很多用于测试关系和验证之类的宏。
如果您只想测试 has_many 关系是否存在,那么您可以执行以下操作:
describe Post do
it should have_many(:categories)
end
或者如果你正在测试一个 has_many :through,那么你会使用这个:
describe Post do
it should have_many(:categories).through(:other_model)
end
我发现Shoulda Rdoc 页面也很有帮助。
【讨论】:
在测试的时候有没有你个人经常做的事情?我正在寻找我应该在开始时立即做的基线事情。诸如...测试我的关联似乎是合理的,但是我应该通过关联测试每种方法吗?或者怎么知道什么时候停止?!大声笑 我真的很喜欢使用这些快速的单行测试,因为它们非常容易设置。我总是从这些开始并添加每一个关系和验证,包括所有通过关联。它不需要太多工作,也不会为您的测试增加太多开销。然后当我添加功能时,我将添加更多的单元测试。如果您在编写代码的同时为模型编写测试,这确实会迫使您编写简单的模块化代码。 如何写has_many通过与expect syntex的关联? 如何处理 rspec 中的源代码。即如果例如:has_many :matched_indices, through: :covariances, source: :matched_indice,dependent: :destroy 我们如何测试这个?【参考方案2】:remarkable 会很好地做到这一点:
describe Pricing do
should_have_many :accounts, :through => :account_pricings
should_have_many :account_pricings
should_have_many :job_profiles, :through => :job_profile_pricings
should_have_many :job_profile_pricings
end
通常,您只需将所有关系从模型复制到规范,然后将“has”更改为“should_have”,将“belongs_to”更改为“should_belong_to”,等等。为了回答它正在测试 Rails 的指控,它还会检查数据库,确保关联有效。
还包括用于检查验证的宏:
should_validate_numericality_of :amount, :greater_than_or_equal_to => 0
【讨论】:
非凡的声音很酷!您是否将它与 rails3 环境一起使用? @Zaz,到目前为止,我已经将它与 Rails 2.2.3 和 2.3.9 一起使用。我相信它也适用于 Rails 3,但我还没有尝试过。【参考方案3】:describe "when Book.new is called" do
before(:each) do
@book = Book.new
end
#otm
it "should be ok with an associated publisher" do
@book.publisher = Publisher.new
@book.should have(:no).errors_on(:publisher)
end
it "should have an associated publisher" do
@book.should have_at_least(1).error_on(:publisher)
end
#mtm
it "should be ok with at least one associated author" do
@book.authors.build
@book.should have(:no).errors_on(:authors)
end
it "should have at least one associated author" do
@book.should have_at_least(1).error_on(:authors)
end
end
【讨论】:
【参考方案4】:为了完整起见,在 2020 年,无需额外宝石即可实现。
it "has many categories" do
should respond_to(:categories)
end
甚至更明确:
it "belongs to category" do
t = Post.reflect_on_association(:category)
expect(t.macro).to eq(:belongs_to)
end
(见Ruby API on Reflection)
第二个示例确保“has_one”不是 与“belongs_to”混淆,反之亦然
然而,它不仅限于 has_many :through 关系,还可以用于应用于模型的任何关联。
(注意:这是在 Rails 5.2.4 中使用 new rspec 2.11 syntax)
【讨论】:
以上是关于Rails RSpec 测试 has_many :through 关系的主要内容,如果未能解决你的问题,请参考以下文章