Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails tips: RSpecの「スパイ(spy)」の解説(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails tips: RSpecの「スパイ(spy)」の解説(翻訳)

RSpecの「スパイ(spy)」は、モックとスタブの組み合わせです。モックやスタブがよくわからない方は、前回記事「Rails tips: RSpecでシンプルなスタブを使う(翻訳)」をご覧ください。

spyは以下の3つの手順の流れにわけられます。

1. セットアップallowでクラスをスタブして、欲しいレスポンスを取得する。
2. エクササイズ: テストされたメソッドを実行する
3. 検証: expecthave_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 または連絡用フォームにてお気軽にお問い合わせください。

関連記事

Rails tips: RSpecでシンプルなスタブを使う(翻訳)

ソフトウェアテストでstubを使うコストを考える(翻訳)

[Rails] RSpecのモックとスタブの使い方


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。