既存RailsアプリにRspecを入れる
インストール
Gemfileに追記
group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'database_cleaner' end
RSpecの設定
必要なファイルが作成される。
bundle install
bundle exec rails generate rspec:install
設定をする
config/application.rb
# config/application.rb config.generators do |g| # 不要なファイルを生成しない g.test_framework :rspec, fixtures: true, view_specs: false, helper_specs: false, routing_specs: false, controller_specs: true, request_specs: false # テストデータのパス設定 g.fixture_replacement :factory_bot, dir: "spec/factories" end
spec/rails_helper.rb
# spec/rails_helper.rb RSpec.configure do |config| # 略 # user = FactoryBot.create(:user) -> user = create(:user) とかけるようにする config.include FactoryBot::Syntax::Methods # Time.zone.nowを、スライドできるようにする config.include ActiveSupport::Testing::TimeHelpers end
spec/spec_helper.rb
# spec/spec_helper.rb require 'database_cleaner' # 略 RSpec.configure do |config| # 略 # テスト後にDBのデータを消す設定 config.before(:suite) do DatabaseCleaner[:active_record].strategy = :transaction DatabaseCleaner.clean_with(:truncation) end config.around(:each) do |example| DatabaseCleaner.cleaning do example.run end end # 略 end
テストデータ/テストコードを書く
development環境のDB構造をtest環境へクローンする
bundle exec rake db:test:clone
テストデータを作る
# spec/factories/my_app/subscription.rb FactoryBot.define do # class: でどのクラスのインスタンスを作るか指定できる factory :subscription, class: ::MyApp::Subscription do user_id 1 course_id 1 status nil # 引数で与えられた値で属性を変えることができる trait :trial do status :trial end trait :contracted do status :contracted end # 関連テーブルも一緒に作る場合 trait :with_entitlements do after(:build) do |subscription| subscription.entitlements << FactoryBot.build(:entitlement__svod) end end end end
テストコードを書く
# spec/models/my_app/subscription_spec.rb require 'rails_helper' describe ::MyApp::Subscription do before do # createはDB保存された状態のインスタンスを作る # beforeで定義した変数はインスタンス変数にしないと内部で参照できない @user = create(:user) end describe 'お試し契約する (テスト対象を書く)' do context '契約可能期間のとき (条件を書く)' do before do # 引数つきで属性を変える / buildeだとDB保存はしない @subscription = build(:subscription, :trial, :with_entitlements) end it '保存できる (期待する結果を書く)' do result = @subscription.save expect(result).to be_truthy # expect(result).to eq true でもOK end end context '契約可能でない期間のとき' do before do @subscription = build(:subscription, :trial, :with_entitlements) end # 時間移動はaroundでも書ける # around do |e| # travel_to('2016-2-29 10:00'.to_time){ e.run } # end it '保存できない' do # このブロック内でTime.zone.nowが1年後になる travel 1.year result = @subscription.save expect(result).to be_falsey # travel_back すると Time.zone.nowが戻る end end end end
実行する
# ファイル指定 bundle exec rspec spec/models/my_app/subscription_spec.rb # ディレクトリ以下実行 bundle exec rspec spec/