my coredump

自分用の公開メモです。主にプログラムのこととか書くはず。

RSpecでデフォルトであるクラスのインスタンスメソッドをスタブにしたい

外部APIとかテスト中は常にスタブにしたいときに、個々のspecで設定するのが面倒だし忘れそうなケース。

こんな :spec/support/xxx_helper.rb を作っておいて

module XxxHelper

  # テスト全体で共通の前処理
  shared_context 'common_before', common_before: true do
    before :all do
      # 全体の前処理(あれば)
    end

    before :each do
      # Userがtweetというメソッドを持っている場合
      allow_any_instance_of(User).to receive(:tweet).and_return(true)
    end
  end
end

以下のように spec/request/xxx_spec.rbinclude_context するか

require 'rails_helper'

describe Xxx do
  include_context 'common_before'
end

もしくは以下のように describe で宣言的に指定する。

require 'rails_helper'

describe Xxx, common_before: true do
end

spec/rails_helper.rbspec/support 以下を読み込む設定をコメントインするのを忘れずに。

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

また個々のspecで expect_any_instance_of で上書きすればスタブ化したメソッドが呼ばれたか調べたいときも対応できる。

describe 'some_spec' do
  before :each do
   expect_any_instance_of(User).to receive(:tweet).and_return(true)
  end
  it 'xxxxx' do
    # xxxxx
  end
end

簡単だけど以上。