RSpecの便利な機能Tips


RSpecの中でよく使う機能をいくつか紹介します。


🏀 RSpecでスタブの作成

allowメソッドでスタブ(テストの際、そのモジュールの代わりに用いる代用品)を構築できます。

RSpec.describe "Specifying a return value" do
it "returns the specified return value" do
dbl = double
allow(dbl).to receive(:foo).and_return(14)
expect(dbl.foo).to eq(14)
end
end

allow_any_instance_ofを使うと生成されたインスタンスすべてに対して、スタブを設定できます。

RSpec.describe "allow_any_instance_of" do
it "returns the specified value on any instance of the class" do
allow_any_instance_of(Object).to receive(:foo).and_return(:return_value)
o = Object.new
expect(o.foo).to eq(:return_value)
end
end

🍮 例外処理のテスト

エラーを通知するような場合のRSpecは次のように記述します。

RSpec.describe "calling a missing method" do
it "raises" do
expect { Object.new.foo }.to raise_error(RuntimeError, 'oops')
end
end

🐮 ログのテスト

Railsでログのテストを行いたい場合は次のように記述します。

it 'writes some message in log' do
expect(Rails.logger).to receive(:info).with(some message)
do_something() # 実際の動作を行う
end

🐠 FactoryGirlで連番を付ける

FactoryGrilで同じ値にならないように連番をつけていくのはsequenceです。

sequence(:email) { |n| "person#{n}@example.com" }

👽 aggregate_failures:テストをまとめて検証

RSpec 3.3からの新機能aggregate_failuresを使うと

  • テストのセットアップ部分を共通化(毎回実行しないように分離)
  • 複数テストを書いて一部が失敗してもすべて検証

を実現できます。

require 'spec_helper'
describe 'Slow spec' do
let(:names) { %w(John Mark Nick) }
before do # テストのセットアップ部分
puts "Waiting..."
sleep 3
puts "OK."
end
it 'has valid items' do
# 検証するテストの対象
aggregate_failures 'testing items' do
expect(names.size).to eq 2
expect(names.uniq).to contain_exactly(*names)
expect(names).to include 'Curl'
end
end
end

これを全体に適用する場合は、spec/spec_helper.rbに次のように記述します。

RSpec.configure do |config|
config.define_derived_metadata do |meta|
meta[:aggregate_failures] = true
end
end

🍣 文字列・配列の後ろ側のマッチャー:end_with

end_withは文字列・配列の後ろ側が期待どおりかをチェックするためのマッチャー(matcher)です。

expect("this string").to end_with "string"
expect("this string").not_to end_with "stringy"
expect([0, 1, 2]).to end_with 1, 2

🍄 時間の掛かったSpecを表示する

RSpecの実行後に、時間の掛かったSpecをn件表示する設定です。プロジェクト直下の.rspecに以下を追記します。

--profile 任意の数

😎 警告をエラーにする

RSpecで警告が発生する場合はエラーにする設定。spec/rails_helper.rbに以下を追記。

RSpec.configure do |config|
config.raise_on_warning = true # 警告をエラーにする
config.raise_errors_for_deprecations! # 非推奨警告をエラーに変換
end

🚌 補足:itspecifyの使い分け

人間の読みやすい自然言語的な使い分けを心がける。

  • it => itを主語として使うと自然な場合に使う
  • specify => 明示する、明記するなどの意味。itを主語似できないような場合に使う

🎂 補足:初心者向けドキュメント

Everyday Rails - RSpecによるRailsテスト入門

RSpecの書き方をサンプルアプリケーションを例に順番に学ぶことができる電子書籍です。RSpecを書き始めた人が最初に読むのに最適な日本語ドキュメントです。

🎉 補足:実践的なRSpecスタイルガイド

RSpec スタイルガイド

可読性が高く、無駄のない効率的なテストを作っていくのに適したRSpecのスタイルガイドです。RSpecを書いていく中で身についたノウハウが詰まっているので初心者〜中級者向けにオススメです。

🗻 参考リンク

📚 おすすめの書籍