はじめに
RSpecでスタブをはさんで必要な検証に集中する事があると思います。
現場で「例えばこうなんやで」とドヤ顔したいだけのメモ書きです。
前準備
本モデルに価格(price
)があるとします。
カラムに価格(price
)を持たせたいところですが、大人の事情でいろんなテーブルと結合して複雑な計算をします。利益率とかあるやん、しらんけど。
モデル
税込価格を計算して返すメソッドBook#price_in_tax
を考えてみましょう。
class Book < ApplicationRecord
def price_in_tax
(price * 1.08).round
end
private
def price
# すごく時間のかかるややこしい処理
# 他のテーブルとかと結合して、テスト用データを用意するだけで嫌になるやつ
end
end
テスト
価格は100円として、税込価格108円が得られるテストを書いてみましょう。
価格を取得するだけで相当めんどうなので、こういうときにスタブを利用すると便利です。
Book#price_in_tax
は税込価格が得られることを検証したいことなのでスタブをはさんでシンプルにしても問題ないでしょう。
require 'rails_helper'
RSpec.describe Book, type: :model do
describe '#price_in_tax' do
before do
@book = Book.new
allow(@book).to receive(:price).and_return(100)
end
it { expect(@book.price_in_tax).to eq(108) }
end
end
気をつけていること
- 検証対象をスタブにしない
Book#price_in_tax
をスタブにすると、都合のいい値しか返せないので税込価格が計算できてるとは限らない。
require 'rails_helper'
RSpec.describe Book, type: :model do
describe '#price_in_tax' do
before do
@book = Book.new
allow(@book).to receive(:price_in_tax).and_return(108)
end
it { expect(@book.price_in_tax).to eq(108) }
end
end
- 期待値の計算にスタブは利用しない
スタブのメソッドはあくまで検証に必要なもので、期待したものを得るための一部だから期待値の計算に利用するのは少し抵抗があります。
require 'rails_helper'
RSpec.describe Book, type: :model do
describe '#price_in_tax' do
before do
@book = Book.new
allow(@book).to receive(:price).and_return(100)
end
it do
price_in_tax = @book.send(:price) * 1.08
# こちらのほうがいくぶんかまし
# price_in_tax = 100 * 1.08
expect(@book.price_in_tax).to eq(price_in_tax)
end
end
end