Techioz Blog

Ruby on Rails テスト – バリデーターをリセット/リフレッシュしますか?

概要

構成変数に依存する検証を持つ RoR Gem のテストを作成しています。

class MyModel < ApplicationRecord
  validates_length_of :field_name, minimum: GemName.minimum_field_length
end

この構成オプションが期待どおりに機能することを確認できますが、テストでカバーされていることを確認したいと思います。

class MyModelTest < ActiveSupport::TestCase
  test "field length is validated" do
    model = MyModel(field_name: 'a' * 25

    # Default minimum length is 20
    assert model.valid?

    # Test different length validation
    GemName.minimum_field_length = 30
    assert_not model.valid?
  end
end

2 番目のアサーションは失敗します (モデルは有効です)。そこにデバッガーを追加して検査すると、GemName.minimum_field_length は 30 を返し、変更されたことを示しますが、MyModel.validators の結果を見ると、最小値は元のデフォルト値の 20 のままです。おそらくこれは、バリデーターは、テストの開始時またはモデルが最初に呼び出されたときに一度作成されます (構成を変更した後に MyModel の新しいインスタンスを作成しようとしましたが、うまくいきませんでした)。テスト中に新しい構成値でモデルバリデーターを更新する .reset_column_information に似た方法はありますか?

解決策

問題は、このような検証で最小長を定義することです。

validates_length_of :field_name, minimum: GemName.minimum_field_length

その後、ファイルが初めて読み取られるときに 1 回だけ最小値が設定されます。 GemName.minimum_field_length が変更されても、バリデーターの構成は変更されなくなります。

ただし、代わりにラムダを使用してバリデーターを初期化すると、ラムダはバリデーター呼び出しごとに評価されるため、変更を取得する必要があります。

代わりにこれを試してください:

validates_length_of :field_name, minimum: -> { GemName.minimum_field_length }

フィールドの最小長が gem の設定された最小長と等しいことだけを確認したい場合は、次のように、両方の値が等しいかどうかを確認するテストを作成するとよいでしょう。

minimum_field_name_length = MyModel.validators_on(:field_name)
                                   .select { |v| v.is_a?(LengthValidator) }
                                   .first
                                   .options[:minimum]

assert_equal minimum_field_name_length, GemName.minimum_field_length