mcpField
R
rspec-service-testing

rspec-service-testing

github.com/midudevテスト・品質7.0k57 回インストール1 週間前に更新
リポジトリ

rspec-service-testing について

Ruby と Rails の開発者向けに、サービスクラスの RSpec テスト作成を支援するスキルです。公開契約の検証を重視し、テストの作成、実行、確認、修正を順に進めます。

主な機能

  1. 01公開契約に基づくサービスのテスト
  2. 02instance_double による単体テストの分離
  3. 03create によるデータベース統合テスト
  4. 04API レスポンス用ハッシュファクトリー
  5. 05テスト手順とチェックリスト

活用シーン

  1. 01サービスの成功・エラー経路のテスト
  2. 02単体テストとDB統合テストの使い分け
  3. 03API レスポンス用ハッシュデータの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/midudev/autoskills --skill rspec-service-testing

インストール後、Claude Code で/rspec-service-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

PATTERNS.md
assets/
spec_examples.md
testing_checklist.md

詳細

RSpec サービスのテスト

spec/services/ 配下のサービスクラスのテストを書くときに、このスキルを使用します。

基本原則: 内部実装ではなく、公開されている契約(.call、.find、.search)をテストします。分離には instance_double を、統合テストには create を使用します。

ワークフロー:作成 → 実行 → 検証 → 修正

1. WRITE:   Write the spec (happy path + error cases + edge cases)
2. RUN:     bundle exec rspec spec/services/your_service_spec.rb
3. VERIFY:  Confirm failures are for the right reason (not a typo or missing factory)
4. FIX:     Implement or fix until the spec passes
5. SUITE:   bundle exec rspec spec/services/ — verify no regressions

ステップ 1 のテストを作成し、正しい理由で失敗することを確認する前に、サービスを実装してはいけません。

クイックリファレンス

項目ルール
ファイルの場所spec/services/module_name/service_spec.rb
Subjectsubject(:service_call) { described_class.call(params) }
単体テストの分離協調オブジェクトには instance_double を使用
統合テストDB を使用するテストには create を使用
複数のアサーションaggregate_failures
状態の検証change マッチャー
時間に依存するテストtravel_to
API レスポンスFactoryBot のハッシュファクトリー(class: Hash)

Spec のテンプレート

# frozen_string_literal: true

require 'spec_helper'

RSpec.describe ModuleName::MainService do
  describe '.call' do
    subject(:service_call) { described_class.call(params) }

    let(:shelter) { create(:shelter, :with_animals) }
    let(:params) do
      { shelter: { shelter_id: shelter.id }, items: %w[TAG001 TAG002] }
    end

    context 'when input is valid' do
      before { create(:animal, tag_number: 'TAG001', shelter:) }

      it 'returns success' do
        expect(service_call[:success]).to be true
      end
    end

    context 'when shelter is not found' do
      let(:params) { super().merge(shelter: { shelter_id: 999_999 }) }

      it 'returns error response' do
        expect(service_call[:success]).to be false
      end
    end

    context 'when input is blank' do
      let(:params) { { shelter: { shelter_id: nil }, items: [] } }

      it 'returns error response with meaningful message' do
        aggregate_failures do
          expect(service_call[:success]).to be false
          expect(service_call[:errors]).not_to be_empty
        end
      end
    end
  end
end

単体テストを分離するには instance_double を使用します。

let(:client) { instance_double(Api::Client) }
before { allow(client).to receive(:execute_query).and_return(api_response) }

統合テストには create を使用します。

let(:source_shelter) { create(:shelter, :with_animals) }

API レスポンス用の FactoryBot ハッシュファクトリー

API クライアントをテストする場合は、class: Hash と initialize_with を使用して、ハッシュ形式のレスポンスフィクスチャを作成します。最小限の例を示します。

FactoryBot.define do
  factory :api_animal_response, class: Hash do
    tag_number { 'TAG001' }
    status     { 'active' }

    initialize_with { attributes.stringify_keys }
  end
end

# In the spec:
let(:api_response) { build(:api_animal_response, tag_number: 'TAG002') }

パターン全体とファクトリーの配置に関するガイダンスは、PATTERNS.md を参照してください。

新しいテストファイルのチェックリスト

  • メインの処理に対して subject を定義している
  • 単体テストには instance_double、統合テストには create を使用している
  • 各公開メソッドに対する正常系のテストがある
  • エラーケースとエッジケース(空の入力、無効な参照、失敗)がある
  • 該当する場合は部分的な成功シナリオがある
  • 繰り返されるパターンに shared_examples を使用している
  • 複数アサーションのテストに aggregate_failures を使用している
  • 状態の検証に change マッチャーを使用している
  • エラーログ出力に対するロガーの期待値を設定している

よくある間違い

間違い正しい方法
エラーケースのテストがない正常系だけでは誤った安心感につながります。必ず失敗ケースもテストしてください
あらゆる場所で let! を使うセットアップで値が必ず必要な場合を除き、遅延評価される let を使用します
ファクトリーのセットアップが大きすぎるファクトリーは最小限に保ち、テストに必要な属性だけを指定します
動作が変わっていないのに実装変更で Spec が失敗するリファクタリングで失敗するテストは、契約ではなく内部実装をテストしています

関連スキル

スキル組み合わせるタイミング
rspec-best-practices一般的な RSpec のスタイルと TDD の原則について
ruby-service-objectsテスト対象となるサービスの規約について
ruby-api-client-integrationAPI クライアント層のテストパターンについて
rails-engine-testingエンジン固有のサービスをテストする場合

アセット

コメント