【问题标题】:Correct way of testing "associations" with Rspec?使用 Rspec 测试“关联”的正确方法?
【发布时间】:2023-03-10 00:20:01
【问题描述】:

我正在尝试测试以下场景:

-> 我有一个名为 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 属性设置为可访问(批量分配)。

【问题讨论】:

    标签: ruby-on-rails rspec associations


    【解决方案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以确保正确设置外键。检查这个stackoverflow.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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多