Shoulda-machersを使うと素晴らしく簡潔かつ直感的にテストをかけるようになるので導入してみることに。しかしインストールして試してみたはいいものの、どうにもこうにも NoMethodError: undefined method `validate_numericality_of'
などとあらゆるメソッドが無いよ、とエラーが吐かれハマったのでメモ。パーフェクトRuby on Railsのサンプルコードでハマった方は特におすすめ。
環境
- Rails 4.2.6
- rspec-rails 3.4.2
- shoulda-matchers 3.1.1
導入方法
1. Gemfileにrspec-railsとshoulda-matchersを追加
# /Gemfile
# development・test環境双方でrspec-railsが必要
group :development, :test do
gem "rspec-rails"
end
group :test do
gem "shoulda-matchers"
end
2. rails_helperにてshoulda-matchersを動かす設定をする
まずはshoulda-matchersを読み込んであげる。
# /spec/rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'shoulda/matchers' # こいつを追加してあげる
さらに同ファイルで設定を追加する
# /spec/rails_helper.rb
Shoulda::Matchers.configure do |config|
config.integrate do |with|
# 今回はRspecを使うのでこのように設定
with.test_framework :rspec
# shoulda-matchersを使いたいテストライブラリを指定
with.library :active_record
with.library :active_model
with.library :action_controller
# Or, choose the following (which implies all of the above):
with.library :rails
end
end
3. spec/models/hoge_spec.rbでrails_helperを読み込む
# /spec/models/hoge.rb
require 'rails_helper'
RSpec.describe Hoge, type: :model do
(テストコードを書く)
end
これで、ひとまずShoulda-matchersを動かすための設定は完了しました。テストコードを書けば動いてくれます。ってことで、以下でサンプルとして実際のモデルテストを書いてみます。
4. テストコードを書いてRspecを走らせる
# /spec/models/hoge.rb
require 'rails_helper'
RSpec.describe Hoge, type: :model do
describe '#name' do
it { should validate_presence_of(:name) }
it { should validate_length_of(:name).
is_at_least(4).
is_at_most(16).
with_message("4文字以上16文字以下で入力してください")
}
end
end
期待に応えるようにモデルにバリデーションを追加してあげます。
# /models/hoge.rb
class Hoge < ActiveRecord::Base
validates :name, length: { in: 4..16, message: '4文字以上16文字以下で入力してください'}, presence: true
end
そんでもって実行してみると
# ターミナル
tacuma:sample tacuma$ rspec
.
Finished in 0.14455 seconds (files took 6.22 seconds to load)
1 examples, 0 failures
無事、テストが走り、モデルテストが行なえるようになりました。