【问题标题】:Rails RSpec Tests for a has_many :through RelationshipRails RSpec 测试 has_many :through 关系
【发布时间】: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

我还缺少什么?谢谢!!

【问题讨论】:

    标签: ruby-on-rails ruby rspec has-many has-many-through


    【解决方案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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-21
        • 1970-01-01
        相关资源
        最近更新 更多