Rubyテストのスタブ実装・カバレッジ計測

Rubyのテストは標準のminitestでかなりカバーできますが、スタブ・モック・カバレッジについては、追加gemを利用した方が良いでしょう。

mochaテストダブル

mocha gemが提供するスタブやモックは、テスト対象のコードが呼び出している一部のメソッドを置き換える機能です。

たとえば、マイクロサービス構成の1サービスをテストするためには、API呼び出ししている部分を差し替えないとテストできません。

minitestにもスタブとモックの機能はありますが、オブジェクトを直接指定して定義するため、以下のような強い制約があります。

  • インスタンスメソッドを事実上置き換えられない
  • クラスメソッドを置き換えられるが、事実上1メソッドに限られる

mochaを利用すると、とくにスタブは柔軟に指定でき便利です。

インストールは、bundlerのGemfileにmochaを追加指定してbundle installです。

gem 'mocha'

単純なスタブの例として、インスタンスメソッドを置き換える場合、対象のクラスにany_instanceを指定したうえで、stubs(), returns()により、メソッドと戻り値を定義します。

require 'mocha/minitest'

def setup
  SomeController.any_instance.stubs(:some_method).returns({ status: :ok, message: 'replaced' })
end

後続のテストケース内で該当のメソッドが呼び出されると、returns()に定義した値で処理が続行します。
また、any_instanceを省略すると、クラスメソッドを差し替えます。

mochaはminitestに限らず、Railsのテストとも組み合わせて利用できます。test_helper.rbでrequireしておけば、各テストでは、mochaのメソッドを呼び出せます。

Railsのコントローラーはテストフレームワークが自動でインスタンスを作るため、インスタンスメソッドの差し替えにはany_instanceが必要になります。
また、実サービスが返さないような異常値なども簡単に実装できるため、将来の変更に対しても準備できる点も優れています。

カバレッジ計測

カバレッジ計測には simplecov を使います。 Gemfileのtest環境向けブロックでsimplecovをインストールしておきます。

gem 'simplecov', require: false

test/testhelper.rbの冒頭でrequireします。アプリケーションのロード前にrequireしないとカバレッジを適切に計測できません。

require 'simplecov'

計測の設定はプロジェクトルートに.simplecovというファイルを以下の内容で作成しています。

SimpleCov.start do
  # exclude uneeded dirs
  add_filter ['test/', 'config/']

  add_group "Models", "app/models"
  add_group "Controllers", "app/controllers"
  add_group "Helpers", "app/helpers"
end

設定が完了したら、あとはrails testなどのテストランナーを一般的な手順で実行するだけです。レポートはcoverageディレクトリに生成されます。レポートは人が読むためのファイルであるため、.gitignoreでcoverageディレクトリを除外するのが適切でしょう。

なお、テストコードを1つも書いていないクラスはカバレッジの母数にも含まれないため、まずは広く薄くテストケースを書いておいた方が把握しやすくなります。

⁋ 2020/12/02↻ 2026/10/08