LoginSignup
10
11

More than 5 years have passed since last update.

【RSpec】Validatorのテストを限界まで手抜きする

Last updated at Posted at 2015-06-23

Validatorのテストを限界まで手抜きする

TL;DR

RSpec::ValidatorHelper

rspec-validator_spec_helperというgemがある.
これが提供するRSpec::ValidatorSpecHelperはvalidatorのテストを簡単化するためのものである.
このクラスは以下の機能を提供する.

  • validate対象になるダミーのクラスの提供
  • ダミークラスのvalidatesvalidates_withの設定
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

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

さらなる単純化

RSpec::ValidatorSpecHelperはダミークラスを提供するのがメインだが,その副作用でテストコードをパラメタライズドテストに落としやすくなるというものがある.

Parameterized Test とは、まさに似たようなテストメソッドをテストデータだけ変えて複数件実行することができる手段で、多くの場合テスティングフレームワークの拡張機能として提供されています。

これであなたもテスト駆動開発マスター!?和田卓人さんがテスト駆動開発問題を解答コード使いながら解説します~現在時刻が関わるテストから、テスト容易性設計を学ぶ #tdd|CodeIQ MAGAZINE

Validatorは何かしらの入力に対してtrue/falseを出力するだけで副作用がないものがほとんどなので,そもそもパラメタライズドテストにしやすいという特徴がある.
RSpec::ValidatorSpecHelperがテストコードを規約で縛る役割を果たすので,よりパラメタライズドテスト化しやすくなる.

そこで,先ほどのサンプルコードをrspec-parameterizedを利用してリファクタリングしてみる.

describe NotOverlappedValidator, type: :validator do
  let(:attribute_names) { [:begin_at, :end_at] }

  where(:begin_at_str, :end_at_str, :be_valid_or_invalid) do
    [
      ["2014-12-24T12:00:00+09:00", "2014-12-24T09:00:00+09:00", be_invalid],
      ["2014-12-24T12:00:00+09:00", "2014-12-24T19:00:00+09:00", be_valid]
    ]
  end

  with_them do
    let(:begin_at) { Time.parse(begin_at_str) }
    let(:end_at) { Time.parse(end_at_str) }
    it { is_expected.to be_valid_or_invalid }
  end
end

このサンプルはパラメータが長いのでちょっとだけ見栄えが悪いが,結構スッキリしたと思う.
これはテストケースが増えれば増えるほど効果がある.
逆に言うと,テストケースを増やしてもテストの複雑さには全く影響を及ぼさない
また,ActiveModel::EachValidator継承クラスのテストにはより効果が高いような気がしなくもない.

Conclusion

パラメタライズドテストたのしい

References

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11