Rails4のconcernsなmoduleのテストをrspecで書く方法
Railsとcapybaraで何かをドラッグアンドドロップしてソートするテストを書くではカテゴリをソートするfeaturesなテストを書いたけど、アレには当然modelのテストもある。
モデルにはCategory.reorderという並び替えを行うメソッドがあって、これのテストはcategory_specに書いていた。
が、別の種類のカテゴリが必要になり、もともとあったCategoryと同じ仕様でソートができる仕様であったため、FooCategoryとBarCategoryに分け、このソート処理をconcernsの下にCategorySortable moduleとして切り出した。
app/models/concerns/category_sortable.rb
module CategorySortable extend ActiveSupport::Concern included do acts_as_nested_set end module ClassMethods def reorder(ids) # some logic here.... end end end
このmoduleをテストするのはどうしたものか、と調べていたところ、rspecにはそれを意図した仕組みが用意されていた。
https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/example-groups/shared-examples!
具体的な手順としては、まず肝になるmodule部分のテストを以下のように書く。
spec/support/models/concerns/category_sortable_spec.rb
require 'spec_helper' shared_examples "category sortable" do describe ".reorder" do before do described_class.reorder([category3.id, category1.id, category2.id]) end it { expect(described_class.roots).to eq [category3, category1, category2] } end end
supportの下に配置しているのは、ここだとspec実行時にロードされるからで、個別にrequireしたり、別途ロードするpathを設定したりするんだったらどこでもいいと思う。ただ、個別にrequireした場合、1度のテストで複数回呼ばれるような実行の仕方をすると以下のようなwarningがでてウザいのでおすすめしない。
追記)_specをつけても2回読み込まれてwarningがでる。
WARNING: Shared example group 'category sortable' has been previously defined at:
~snip~
で、このmoduleをincludeするmodelのテストはこんなかんじになる。
spec/models/foo_category_spec.rb
require 'spec_helper' describe FooCategory do ~ some class specific tests ~ it_behaves_like "category sortable" do let(:category1) { FactoryGirl.create(:foo_category) } let(:category2) { FactoryGirl.create(:foo_category) } let(:category3) { FactoryGirl.create(:foo_category) } end end
spec/models/bar_category_spec.rb
require 'spec_helper' describe BarCategory do ~ some class specific tests ~ it_behaves_like "category sortable" do let(:category1) { FactoryGirl.create(:bar_category) } let(:category2) { FactoryGirl.create(:bar_category) } let(:category3) { FactoryGirl.create(:bar_category) } end end
ということで、moduleのテスト側でshared_examplesで定義したものをit_behaves_likeで呼び出すかっこうになる。ここでdescribeしてるクラスがさっきのmoduleのテストのdescribed_classに該当する。テストの呼び出し方はもうちょっとバリエーションがあるので、この書き方がフィットしないケースは上記のRspecドキュメントを熟知すべし。
なお、コピペで同じテストを書くものはリア充が地獄の火の中に投げ込むものであり、腹を切って死ぬべきである。
以上、よろしくお願いいたします。
- 出版社/メーカー: 任天堂
- 発売日: 2013/11/21
- メディア: Video Game
- この商品を含むブログ (27件) を見る