概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Ruby on Rails / RSpec - spies test pattern explained
- 原文公開日: 2018/01/26
- 著者: Paweł Dąbrowsk
Rails tips: RSpecの「スパイ(spy)」の解説(翻訳)
RSpecの「スパイ(spy)」は、モックとスタブの組み合わせです。モックやスタブがよくわからない方は、前回記事「Rails tips: RSpecでシンプルなスタブを使う(翻訳)」をご覧ください。
spyは以下の3つの手順の流れにわけられます。
1. セットアップ: allow
でクラスをスタブして、欲しいレスポンスを取得する。
2. エクササイズ: テストされたメソッドを実行する
3. 検証: expect
とhave_received
を用いて、コードがexpectationを満たしているかどうかをテストする
サンプルのクラスで実装を見てみることにしましょう。
class UserService
def initialize(user:, name:)
@user = user
@name = name
end
def save_name
name_service = NameService.new(name: name)
user.update_attribute(:name, name_service.get_name(format: :short))
end
private
attr_reader :user, :name
end
require 'spec_helper'
describe UserService do
describe "#save_name" do
# セットアップ
name_service = instance_double(NameService, get_name: double)
user = instance_double(User, update_attribute: double)
short_name = 'Nick'
name = 'Nick Martin'
allow(NameService).to receive(:new).with(name: name).and_return(name_service)
allow(name_service).to receive(:get_name).with(format: :short).and_return(short_name)
allow(user).to receive(:update_attribute).with(:name, short_name)
# エクササイズ
user_service = UserService.new(user: user, name: name)
user_service.save_name
# 検証
expect(name_service).to have_received(:get_name).with(format: :short)
expect(user).to receive(:update_attribute).with(:name, short_name)
end
end
訳注: specに
it
ブロックがありませんが、省略されているようです。
もちろんもっと速い書き方はありますが、特に複雑なテストケースではspyを使うと明快になるので、このテスト全体をいくつかのセクションに分割しました。
Railsでお困りの方にお知らせ
知りたいことがありましたら、twitter または連絡用フォームにてお気軽にお問い合わせください。