35
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2020-02-25

Overview

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

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

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

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

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')
35
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?