Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

RSpec でクラスメソッドとインスタンスメソッドを mock 化する

Overview

この記事ではクラスメソッドとインスタンスメソッドを、テスト対象に都合の良いデータを返してくれるように mock 化する方法を紹介します。

(自動テスト界隈では「本物のふりをしてくれるオブジェクト」をまとめてテストダブルと言い、テスト対象からの出力を受けるのが mock で、テスト対象に都合の良いデータを返してくれるのが stub と言いうのでは?という方がいらっしゃるかと思いますが、この記事ではこれらの用語の定義はややこしいので触れません... :pray: テストを pass するためにテスト中に都合の良いデータを返す方法という観点だけでお読みください)

テスト中のクラスメソッドの返り値を固定する

では、まずはクラスメソッドからです。
こういうクラスがあったとします。

class ExampleClass
  def self.real_method # クラスメソッドは self で定義
    'real'
  end
end

この real_method の返り値を、テスト中に dummy にしたい場合はこう書きます。

require 'spec_helper'

describe 'ExampleClass' do
  it 'return dummy'
    allow(Example).to receive(:real_method).and_return('dummy')
    puts Example.real_method # dummy
  end
end

テスト中のインスタンスメソッドの返り値を固定する

続いてインスタンスメソッドです。
こういうクラスがあったとします。

class ExampleClass
  def real_method # インスタンスメソッドは self いらない
    'real'
  end
end

テストはこう書きます。

require 'spec_helper'

describe 'ExampleSlass' do
  it 'return dummy' do
    allow_any_instance_of(Example).to receive(:real_method).and_return('dummy')
    puts Example.new.real_method # dummy
  end
end

allow_any_instance_of を使うところがキモですね。

ちなみに、インスタンスメソッドをただの allow で mock しようとすると以下のように Example に real_method というクラスメソッドはないよというエラーを吐かれ、

allow(Example).to receive(:real_method).and_return('dummy')
# Example does not implement: real_method

テスト中に new してインスタンスを mock しようとすると、テストで new したインスタンスと実際のコードで new したインスタンスは異なるので mock ができず、real が返されます。

allow(Example.new).to receive(:real_method).and_return('dummy')
# ここで new しても、実際のコードは別のインスタンスなので real が返される

まとめ

  • クラスメソッド
allow(Class).to receive(:target_method).and_return('mock_value')
  • インスタンスメソッド
allow_any_instance_of(Class).to receive(:target_method).and_return('mock_value')
att55
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away