Ruby on rails 在rails应用程序中独立于模型测试自定义验证功能

Ruby on rails 在rails应用程序中独立于模型测试自定义验证功能,ruby-on-rails,ruby,unit-testing,validation,custom-validators,Ruby On Rails,Ruby,Unit Testing,Validation,Custom Validators,我正在构建一个自定义的验证方法,用于我的rails应用程序。我要构建的验证器类型比较模型中的一列,在模型中,验证器被调用到其他表中的列。下面是一个代码示例,演示了我试图构建的验证器的模式 module ActiveModel module Validations module ClassMethods # example: validate_a_column_with_regard_to_other_tables :column, tables:

我正在构建一个自定义的验证方法,用于我的rails应用程序。我要构建的验证器类型比较模型中的一列,在模型中,验证器被调用到其他表中的列。下面是一个代码示例,演示了我试图构建的验证器的模式

module ActiveModel
    module Validations
        module ClassMethods
            # example: validate_a_column_with_regard_to_other_tables :column, tables: { table_one: :some_column }
            def validate_a_column_with_regard_to_other_tables(*attr_names)
                validates_with WithRegardToOtherTablesValidator, _merge_attributes(attr_names)
            end
        end

        class WithRegardToOtherTablesValidator < EachValidator
            def validate_each(record, attribute, value)
                # compare record, attribute or value to all records that match table: :column in :tables
            end
        end
    end
end
模块动态模型
模块验证
模块类方法
#示例:验证列与其他表的关系:列,表:{table_one::some_column}
def根据其他表格(*属性名称)验证列
使用WITHREGARDTOTHERTABLESVALIDATOR、\u merge\u属性(属性名称)验证\u
结束
结束
使用RegardToertablesValidator
可以使用应用程序和模式中存在的模型对此进行测试。但是,这不是测试验证器的好方法,因为它会将验证器描述为依赖于它不依赖的模型

我能想到的唯一其他方法是在测试中创建一组模型

class ValidateModel < BaseModel
    validate_a_column_with_regard_to_other_tables :column, :tables { compare_to_model: :some_column }
end

class CompareToModel < BaseModel
    attr_accessor :some_column
end
class ValidateModel
但是,无法验证:column是否与:compare_to_model中的:some_column有关,因为:compare_to_model不是架构的一部分

如何在测试中创建作为模式一部分的模拟模型?
或者有更好的方法来测试这样的自定义验证器功能吗?

如果您使用的是
rspec
,您可以设置如下内容:

before(:all) do
  ActiveRecord::Migration.create_table :compare_to_model do |t|
    t.string :some_column
    t.timestamps
  end
end

it "validates like it should" do
  ...
end

after(:all) do
  ActiveRecord::Migration.drop_table :compare_to_model
end
  • 在(:all)之前的
    上有一个注意事项(:all)
    这是一个“全局”设置,因此数据将从一个
    保存到另一个
    上,您可能希望用事务将每个
    包装起来,然后在(:each)
    之前回滚,或者在(:each)
    之前有一个
    清理表

回答得很好!我正在使用Test::Unit。功能
def setup
def teardown
将取代(:all)
之前的
和(:all)
之后的
。这些函数实际上将封装每个
测试
,这是与rspec的
it
等效的test::Unit。