前編はこちら: 【前編】Railsのテストを書く!RSpecで始める失敗しないテスト戦略
実践的なRSpecの書き方
RSpecの基本構文
contextとdescribeの違い
describe User do
context "有効なユーザーの場合" do
it "登録が成功する" do
user = User.new(name: "Alice", email: "alice@example.com")
expect(user).to be_valid
end
end
context "名前が無効な場合" do
it "登録に失敗する" do
user = User.new(name: nil, email: "alice@example.com")
expect(user).to_not be_valid
end
end
end
データセットアップ
FactoryBotで簡略化:
# spec/factories/users.rb
FactoryBot.define do
factory :user do
name { "Test User" }
email { "test@example.com" }
end
end
# spec/models/user_spec.rb
describe User do
it "FactoryBotを使用して作成可能" do
user = create(:user)
expect(user).to be_valid
end
end
よくある失敗例と解決法
テストが冗長になりすぎる
解決策: shared_examplesの活用
RSpec.shared_examples "無効なユーザー" do |field|
it "#{field}が無効である" do
user = User.new(field => nil)
expect(user).to_not be_valid
end
end
describe User do
include_examples "無効なユーザー", :name
include_examples "無効なユーザー", :email
end
外部サービスの依存
WebMockでのモック化例:
# spec/rails_helper.rb
require 'webmock/rspec'
# spec/services/external_service_spec.rb
describe ExternalService do
it "APIからデータを取得する" do
stub_request(:get, "https://api.example.com/data")
.to_return(status: 200, body: '{"key": "value"}', headers: {})
result = ExternalService.new.fetch_data
expect(result).to eq({ "key" => "value" })
end
end
効率的なテスト運用
CI/CDパイプライン
GitHub Actionsの設定例
name: RSpec Tests
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rspec
テストの高速化
データベースリセット戦略:
# spec/rails_helper.rb
RSpec.configure do |config|
config.use_transactional_fixtures = true
end
コメント