雑多記録 -- expect(Some).to receive(:my_method) の記述方法

expect(Some).to receive(:my_method) は何を検証するのか

  • 一つの処理の中で Some が my_method を呼び出していること

どのような場面で使うか

  • ex.) 例外処理内で例外が発生したとき、確かに、例外が発生した後の処理が実行されていないことを確認するとき

イメージ(Rails framework をベースとする)

class SomeController do
  def index
    begin
      @some = Some.all   #=> Some クラスの all メソッドが呼ばれる
      raise
      @some = Some.first #=> Some クラスの first メソッドは呼ばれない
    rescue
    end
  end
end

やるうちに分かった正しい記述方法

  1. 'expect(メソッドを呼び出すことを期待するクラス).to メソッド' を「テスト実行状態を作成する前」に実行する
    1. の後にテスト実行状態を作成する

おそらく基本的な方法

describe SomeController do
  describe '#index' do
    context 'when success' do
      it do
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
        get(:index)
        response
      end
    end
  end
end

DRY な方法

describe SomeController do
  describe '#index' do
    subject do
      get(:index)
      response
    end

    context 'when success' do
      it do
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
        subject
      end
    end
  end
end

NGケース

describe SomeController do
  describe '#index' do
    context 'when success' do
      it do
        get(:index)
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
      end
    end
  end
end
describe SomeController do
  describe '#index' do
    context 'when success' do
      it do
        get(:index)
        response
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
      end
    end
  end
end
describe SomeController do
  describe '#index' do
    subject do
      get(:index)
      response
    end

    context 'when success' do
      it do
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
      end
    end
  end
end
describe SomeController do
  describe '#index' do
    subject do
      get(:index)
      response
    end

    context 'when success' do
      it do
        subject
        expect(Some).to receive(:all)
        expect(Some).not_to receive(:first)
      end
    end
  end
end

検証コード(expect) のあとにテスト実行状態を作成しなければいけない所(get(:index))は違和感がある