はじめに
テストを書くのが嫌い/苦手な人はたくさんいると思う。
ものづくりが好きな人にとってテストはなにも生み出されている気がしなくて退屈だ。
そして、テストでエラーが出てもテストのどこが間違えているのかよくわからない。
なぜ、このテストが通らんのやァって発狂しそうになる。
全部、自分のことだ。
最近はRSpecによるRailsテスト入門という本を参考に自分のRailsアプリにRSpecを書きながら苦手克服を目指している。
この本はとてもわかりやすくまとめられていると思う。
Facebookログイン部分のテストはRSpecによるRailsテスト入門にもあまり詳しく書いていなかったのでここでまとめてみる。
モックを作成する
helperとしてメソッドを定義する。
/spec/support/omniauth_macros.rb
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する。
spec/rails_helper.rb
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ログイン/サインアップを制御するコントローラー
app/controllers/sessions_controller.rb
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を書く
spec/features/users_spec.rb
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で連携したユーザーがログインしようとするとユーザーは増えないことをテストする。