この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。
はじめに
テストを書くのが嫌い/苦手な人はたくさんいると思う。 ものづくりが好きな人にとってテストはなにも生み出されている気がしなくて退屈だ。 そして、テストでエラーが出てもテストのどこが間違えているのかよくわからない。 なぜ、このテストが通らんのやァって発狂しそうになる。 全部、自分のことだ。
最近はRSpecによるRailsテスト入門という本を参考に自分のRailsアプリにRSpecを書きながら苦手克服を目指している。 この本はとてもわかりやすくまとめられていると思う。 Facebookログイン部分のテストはRSpecによるRailsテスト入門にもあまり詳しく書いていなかったのでここでまとめてみる。
モックを作成する
helperとしてメソッドを定義する。
module OmniauthMacros def facebook_mock OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new( { provider: 'facebook', uid: '12345', info: { name: 'mockuser', email: 'sample@test.com' }, credentials: { token: 'hogefuga' } } ) end end
設定する
OmniAuth.config.test_mode = true
はOmniAuthが呼ばれたら実際の通信を行わずにテストモードに入ることを意味する。
config.include OmniauthMacros
は先ほどのhelperをrequireする。
require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../../config/environment', __FILE__) abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } ActiveRecord::Migration.maintain_test_schema! RSpec.configure do |config| config.fixture_path = "#{::Rails.root}/spec/fixtures" config.use_transactional_fixtures = true config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! # -----------以下を追加----------- OmniAuth.config.test_mode = true config.include OmniauthMacros end
Facebookログイン/サインアップを制御するコントローラー
class SessionsController < ApplicationController def callback auth = request.env["omniauth.auth"] user = User.find_by(provider: auth["provider"], uid: auth["uid"]) || User.create_with_facebook(auth) session[:user_id] = user.id redirect_back_or root_path end end
別にOmniAuthでデータをとってくるコードならなんでも良い。
Specを書く
require "rails_helper" describe "UserFeature" do describe "facebook連携でサインアップする" do before do OmniAuth.config.mock_auth[:facebook] = nil Rails.application.env_config['omniauth.auth'] = facebook_mock visit root_path click_link "ログイン" end it "サインアップするとユーザーが増える" do expect{ click_link "Facebookでログイン" }.to change(User, :count).by(1) end it "すでに連携されたユーザーがサインアップしようとするとユーザーは増えない" do click_link "Facebookでログイン" click_link "ログアウト" click_link "ログイン" expect{ click_link "Facebookでログイン" }.not_to change(User, :count) end end end
before節
env['omniauth.auth']
に先ほどのモックをセットし、ログイン画面へのリンクをクリックする。
it節
- 実際にログインを行うボタンをクリックするとユーザーが新しく作成されることをテストする。
- すでに、Facebookで連携したユーザーがログインしようとするとユーザーは増えないことをテストする。