87
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

【Rails】まだValidatorのテストで消耗してるの?

Custom Validator

RailsにおけるCustom ValidatorについてはRuby on Rails Guidesや「てめえらのRailsはオブジェクト指向じゃねえ!まずはCallbackクラス、Validatorクラスを活用しろ!」などの記事に触れられているとおりである.
Modelはごちゃごちゃさせたくないし,Validatorとして切りだしちゃえば使い回しも効くよね!という話(ざっくり).

Validatorのテスト

Custom ValidatorのテストについてはRailsでCustom validatorをテストするにて言及されている.
特定のModelに依存したテストを書くのはおかしな話だからダミーのクラスを用意しよう!みたいな感じ.

let(:model_class) do
  Struct.new(:url) do
    include ActiveModel::Validations

    def self.name
      'DummyModel'
    end

    validates :url, full_http_url: true
  end
end

- RailsでCustom validatorをテストする - Qiita

ただ,これを各Validator Spec毎に毎回書くのは面倒だなーと思う.サボりたい.

RSpec::ValidatorSpecHelper

ということで,Validatorのテストで手抜きするためのgemを作った(izumin5210/rspec-validator_spec_helper).
勝手にダミークラスを生成してvalidatesvalidates_withも設定してくれるというものになっている.

EachValidator継承クラスの場合は1つのカラムにしか依存しないので,letを利用してvalueに値を突っ込むことでvalidateしてくれる.
あとはis_expectedやワンライナーshould等でbe_valid/be_invalidを見てあげればよい(subjectにダミークラスをnewしたものが入ってる).

describe EmailValidator, type: :validator do
  describe '#validate_each' do
    context 'with invalid format address' do
      let(:value) { 'kokoro.pyonpyon' }
      it { is_expected.to_not be_valid }
    end

    context 'with valid foramt address' do
      let(:value) { 'kokoro.pyonpyon@example.com' }
      it { is_expected.to be_valid }
    end
  end
end

EachValidatorじゃない(Validatorを直接継承している)場合は,validationに関係するカラム名をattribute_namesとして渡してあげる.

describe NotOverlappedValidator, type: :validator do
  let(:attribute_names) { [:begin_at, :end_at] }
  let(:begin_at) { Time.parse("2014-12-24T12:00:00+09:00") }

  describe '#validate' do
    context 'when end_at is overlapped' do
      let(:end_at) { Time.parse("2014-12-24T09:00:00+09:00") }
      it { is_expected.to_not be_valid }
    end

    context 'when end_at is not overlapped' do
      let(:end_at) { Time.parse("2014-12-24T19:00:00+09:00") }
      it { is_expected.to be_valid }
    end
  end
end

値を宣言するだけでValidationのテストができるので,とても楽になる.

References

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
87
Help us understand the problem. What are the problem?