4

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

これは、アプリとスキーマに存在するモデルを使用してテストできます。ただし、これは、バリデーターが依存していないモデルに依存していると説明するため、バリデーターをテストする良い方法ではありません。

他に考えられる唯一の方法は、テストで一連のモックアップ モデルを作成することです。

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

ただし、:compare_to_model はスキーマの一部ではないため、:column が :compare_to_model の :some_column と関係があることを検証することはできません。

テストでスキーマの一部であるモック モデルをどのように作成しますか? または、このようなカスタムバリデータ関数をテストするより良い方法はありますか?

4

1 に答える 1

1

を使用している場合は、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
  • 1 つの注意点before(:all)は「グローバル」セットアップであるため、データは一方itから他方に保持されます。それぞれitをトランザクションでラップし、後でロールバックするか、代わりにbefore(:each)テーブルをクリーンアップする必要がある場合があります。
于 2014-01-14T13:36:00.540 に答える