【问题标题】:Creating some class during tests (STI)在测试期间创建一些类(STI)
【发布时间】:2016-09-06 14:19:58
【问题描述】:

我有课

Gate < ActiveRecord::Base
  self.inheritance_column = :kindof
# some methods
end
#  and derived
MoneyHaters < Gate
# some overloaded methods
end

类型列 :kindof 表示 STI

在测试期间,我想创建一个 2-3 个孩子。主要是因为每个派生类在应用程序中必须是唯一的。像这样:

factory :gate do
  before(:create) do
    gate_name  = FFaker::Company.name.gsub( /\s+/,'' )
    gate_class_name = gate_name.singularize.classify
  end

  name { gate_name }

  # I want that next class will be declared in App namespace, like all others.
  gate_class  = Class.new(Gate) do
    def comission_in(amount)
      amount * 0.01 + 5
    end
    def comission_out(amount)
      amount * 0.02 + 5
    end
  end
  Object.const_set( gate_class_name, gate_class )

  type { gate_class_name }
  country { FFaker::Address.country_code }
end

在“Object.const_set”行中使用 rspec 运行代码时出现错误

TypeError: #<FactoryGirl::Declaration::Implicit:0x00000006a1af30 @name=:gate_class_name, @ignored=false, @factory=#<FactoryGirl::Definition:0x00000006ed6df8 @declarations=#<FactoryGirl::DeclarationList:0x00000006ed6dd0 @declarations=[#<FactoryGirl::Declaration::Dynamic:0x00000006ed6998 @name=:name, @ignored=false, @block=#<Proc:0x00000006ed69c0@[skipped]>>, #<FactoryGirl::Declaration::Implicit:0x00000006a1af30 ...>], @name=:gate, @overridable=false>, @callbacks=[#<FactoryGirl::Callback:0x00000006ed6a38 @name=:before_create, @block=#<Proc:0x00000006ed6ba0@[skipped]>>], @defined_traits=#<Set: {}>, @to_create=nil, @base_traits=[], @additional_traits=[], @constructor=nil, @attributes=nil, @compiled=false>> is not a symbol nor a string

但在 Rails 控制台中工作正常

通常我调用 FactoryGirl 工厂来创建对象,但是,如果这是不可能的 - 我想知道有没有其他方法可以做到这一点。

非常感谢任何帮助。

【问题讨论】:

  • 不确定,为什么需要特殊的测试类。你不能使用那些已经存在的吗?
  • 也许,您使用的 STI 不正确?
  • cmets 中的代码不可读。把它放在问题中。
  • 那些新的派生类,当在应用程序中硬编码时 - 必须连接到真正的外部服务。这里我想测试一些用法,不连接外部世界。

标签: ruby-on-rails ruby-on-rails-4 rspec-rails


【解决方案1】:

好的,我花了大约两个小时才发布问题,但我在发布后才找到答案 =)

我只需将类定义移到属性的定义中。

FactoryGirl.define do
  factory :gate do

    name { FFaker::Company.name }
    type { 
      class_name = 'Gate' + name.gsub( /[[:blank:][:cntrl:][:punct:]]/,'' ).to_s.singularize
      gate_class = class_name.classify
      class_instance  = Class.new(Gate) do
        def comission_in(amount)
          amount * 0.01 + 5
        end
        def comission_out(amount)
          amount * 0.02 + 5
        end
      end
      Object.const_set( gate_class, class_instance )
      puts " gate_class: '#{ gate_class }'; name: '#{ name }';"
      class_name
    }
    country { FFaker::Address.country_code }

  end
end

【讨论】:

    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多