使用 Rspec 测试“关联”的正确方法?
Posted
技术标签:
【中文标题】使用 Rspec 测试“关联”的正确方法?【英文标题】:Correct way of testing "associations" with Rspec? 【发布时间】:2013-03-30 21:47:32 【问题描述】:我正在尝试测试以下场景:
-> 我有一个名为 Team 的模型,当它由用户创建时才有意义。因此,每个 Team 实例都必须与一个 User 相关联。
为了测试,我做了以下操作:
describe Team do
...
it "should be associated with a user" do
no_user_team = Team.new(:user => nil)
no_user_team.should_not be_valid
end
...
end
这迫使我将团队模型更改为:
class Team < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :user
validates_presence_of :name
validates_presence_of :user
belongs_to :user
end
这对您来说是否正确?我只是担心将 :user 属性设置为可访问(批量分配)。
【问题讨论】:
【参考方案1】:我通常使用这种方法:
describe User do
it "should have many teams" do
t = User.reflect_on_association(:teams)
expect(t.macro).to eq(:has_many)
end
end
更好的解决方案是使用 gem shoulda,它可以让您简单地:
describe Team do
it should belong_to(:user)
end
【讨论】:
应该实际测试什么?我想确保在创建新团队时它实际上属于用户。Shoulda
将测试它,它将“确保存在 belongs_to 关系”(rubydoc.info/github/thoughtbot/shoulda-matchers/master/Shoulda/…)。因此,您可以放心地假设,当您创建一个新团队时,它将属于一个用户。
我刚刚对此进行了测试,我能够在不指定用户的情况下创建团队。应该只检查模型中是否存在belongs_to。我想确定一个团队有一个与之关联的用户...我相信我需要在创建团队时验证关联用户的存在...
Hommer,我做了一些研究,看来您必须添加validates :user, presence: true
以确保正确设置外键。检查这个***.com/questions/5176510/…
现在任何人的新语法都是expect(t.macro).to eq(:has_many)
。【参考方案2】:
it Idea.reflect_on_association(:person).macro.should eq(:belongs_to)
it Idea.reflect_on_association(:company).macro.should eq(:belongs_to)
it Idea.reflect_on_association(:votes).macro.should eq(:has_many)
【讨论】:
我更喜欢这个解决方案而不是上面的那个。 shoulda gem 打破了我所有的权威测试,虽然有解决方法,但我宁愿避免使用看起来有问题的 gem。 这适用于 Rails 5.0.1、rspec 3.5.0 和 rspec-rails 3.5.2。【参考方案3】:class MicroProxy < ActiveRecord::Base
has_many :servers
end
describe MicroProxy, type: :model do
it expect(described_class.reflect_on_association(:servers).macro).to eq(:has_many)
end
【讨论】:
urbanczykd 的回答重复 @Vasilisa 当前 Rspec 版本的社区约定鼓励使用expect
而不是 should
betterspecs.org/#expect 在测试同一类时,described_class
方法可用于不进行维护的目的用类名blog.eq8.eu/article/…锁定测试
我同意,但你在答案中什么也没说。请把你的解释从评论移到答案【参考方案4】:
RSpec 是一个 ruby 测试框架,而不是一个 Rails 框架。 belongs_to 是一个 rails 构造,而不是 ruby 构造。 像 shoulda-matchers 这样的 Gem 将 ruby 和 rails 连接起来,帮助你编写好的测试。
记住以上内容并遵循官方文档,应该可以帮助您了解最新情况并了解您正在写的内容。
所以,下面是我要写的。
用户模型:
RSpec.describe User, type: :model do
context 'associations' do
it should have_many(:teams).class_name('Team')
end
end
团队模型:
RSpec.describe Team, type: :model do
context 'associations' do
it should belong_to(:user).class_name('User')
end
end
【讨论】:
以上是关于使用 Rspec 测试“关联”的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何测试 belongs_to 与 Rails 6 和 RSpec 4.1 的关联?
使用 rspec 进行 ActionMailer 测试 [关闭]
使用 RSpec 测试 DeserializationError