【问题标题】:Test belongs_to included by concern关注所包含的测试 belongs_to
【发布时间】:2016-10-21 13:12:27
【问题描述】:

我有模特

class Survey < ActiveRecord::Base
  include Respondable
end

在 DB surveys 表中有下一个字段:

  • responses_saved_date
  • responses_saved_by_type
  • responses_saved_by_id

和模块

module Respondable
  extend ActiveSupport::Concern

  included do
    belongs_to :responses_saved_by,    :polymorphic => :true
  end

  def update_saved_settings!(person=nil)
    self.responses_saved_date = Time.now
    self.responses_saved_by   = person
    self.save
  end
end

根据这篇博文https://semaphoreci.com/community/tutorials/testing-mixins-in-isolation-with-minitest-and-rspec,我尝试为负责任的关注编写单元测试,以隔离测试它

这是我的 rspec:

describe Respondable do
  class DummySurvey < ActiveRecord::Base
    include Respondable
  end

  subject { DummySurvey.new }

  it { should belong_to(:responses_saved_by) }

  it 'saves the settings with user' do
    subject.update_saved_settings!(user)

    subject.responses_saved_date.should_not be_nil
    subject.responses_saved_by.should eq user
  end

  it 'saves the settings without user' do
    subject.update_saved_settings!

    subject.responses_saved_date.should_not be_nil
    subject.responses_saved_by.should be_nil
  end
end

当我运行测试时,我收到下一个错误:

Failure/Error: subject { DummySurvey.new }
ActiveRecord::StatementInvalid:
    PG::UndefinedTable: ERROR:  relation "dummy_survey" does not exist
    LINE 5: WHERE a.attrelid = '"dummy_survey"'...
                                 ^
    : SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                         pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
                    FROM pg_attribute a LEFT JOIN pg_attrdef d
                      ON a.attrelid = d.adrelid AND a.attnum = d.adnum
                   WHERE a.attrelid = '"dummy_survey"'::regclass
                     AND a.attnum > 0 AND NOT a.attisdropped
                   ORDER BY a.attnum

【问题讨论】:

    标签: ruby-on-rails ruby testing rspec activesupport-concern


    【解决方案1】:

    我想如果你写

    class DummySurvey < Survey
    

    而不是

    class DummySurvey < ActiveRecord::Base
    

    你应该是金色的。当您定义一个继承自 ActiveRecord::Base 的类时,期望您的数据库具有正确的表和列(通过迁移设置,并由 Rails 命名约定确定)。

    Rails 应该在测试运行后重置测试数据库,因此使用与实际应用相同的模型类是可行的。

    【讨论】:

      【解决方案2】:

      也许一些单独测试它的方法是:

      describe Respondable do
        class DummySurvey
          attr_accessor :responses_saved_date, :responses_saved_by
          def save
            @saved = true
          end
      
          def persisted?
            @saved
          end
      
          def self.belongs_to(association, options = {})
            @associations ||= {}
            @associations[association] = OpenStruct.new(active_record: true, macro: :belongs_to,
              options: options, foreign_key: options[:foreign_key] || "#{association}_id")
          end
      
          def self.reflect_on_association(association)
            @associations ||= {}
            @associations[association]
          end
      
          def self.column_names
            ['responses_saved_by_type', 'responses_saved_by_id']
          end
      
          include Respondable
        end
      
        subject { DummySurvey.new }
        let(:user) { Object.new }
      
        it { should belong_to(:responses_saved_by) }
      
        it 'saves the settings with user' do
          subject.update_saved_settings!(user)
      
          subject.responses_saved_date.should_not be_nil
          subject.responses_saved_by.should eq user
          subject.should be_persisted
        end
      
        it 'saves the settings without user' do
          subject.update_saved_settings!
      
          subject.responses_saved_date.should_not be_nil
          subject.responses_saved_by.should be_nil
          subject.should be_persisted
        end
      end
      

      或者,您可以在测试中为类DummySurvey 创建数据库表或设置现有表的table_name

      class DummySurvey < ActiveRecord::Base
        self.table_name = 'surveys'
        include Respondable
      end
      

      【讨论】:

        猜你喜欢
        • 2013-03-21
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2016-07-10
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 2017-11-29
        相关资源
        最近更新 更多