動作検証環境
- Rails 5.2.3
- rspec-rails 3.8.2
shared_context 作成
- ポイント
- テスト本体で
subject (ここでは send_request)
を使うため、expect
の前にsend_request
を呼ぶ。 - 順序が不定な場合は、json_expressions の
match_json_expression
を使う。
- テスト本体で
spec/support/shared_context_for_api.rb
RSpec.shared_context 'api' do
shared_examples 'http_status_code_200' do
it 'returns 200' do
send_request
expect(response).to be_successful
expect(response.status).to eq(200)
# または以下。お好みで。
# expect(response).to have_http_status(:ok)
end
end
shared_examples 'http_status_code_200_with_json' do
it 'returns 200 with JSON' do
send_request
expect(response).to be_successful
expect(response.status).to eq(200)
expect(JSON.parse(response.body).deep_symbolize_keys).to eq(expected_response)
end
end
shared_examples 'http_status_code_200_with_json_expression' do
it 'returns 200 with JSON' do
send_request
expect(response).to be_successful
expect(response.status).to eq(200)
expect(response.body).to match_json_expression(expected_response)
end
end
shared_examples 'http_status_code_404' do
it 'returns 404' do
send_request
expect(response).to_not be_successful
expect(response.status).to eq(404)
# または以下。お好みで。
# expect(response).to have_http_status(:not_found)
end
end
shared_examples 'http_status_code_500' do
it 'returns 500' do
send_request
expect(response).to_not be_successful
expect(response.status).to eq(500)
end
end
end
shared_context 利用
- ポイント
include_context 'api'
-
it_behaves_like 'http_status_code_200'
('http_status_code_200'
に ↑のshared_examples
で定義したものを指定する)
spec/requests/users_spec.rb
RSpec.describe Api::V1::UsersController, type: :request do
include_context 'api'
describe 'GET /api/v1/users' do
context 'without params' do
subject(:send_request) { get '/api/v1/users' }
let(:expected_response) { ... }
before { create_list(:user, 2) }
it_behaves_like 'http_status_code_200_with_json'
end
end
describe 'GET /api/v1/users/:email' do
context 'when the user exists' do
subject(:send_request) { get "/api/v1/users/#{@user.id}" }
let(:expected_response) { ... }
before { @user = create(:user) }
it_behaves_like 'http_status_code_200_with_json'
end
context 'when the user does not exist' do
subject(:send_request) { get '/api/v1/users/non_existing_user_id' }
it_behaves_like 'http_status_code_404'
end
end
end
expected_response
としてJSONを使うパターン
describe 'GET /api/v1/endpoint' do
context 'with valid request' do
subject(:send_request) { get '/api/v1/endpoint' }
let(:expected_response) do
JSON.parse(file_fixture('endpoint_response_index.json').read, symbolize_names: true)
end
it_behaves_like 'http_status_code_200_with_json_expression'
end
end
subject
を使わずbefore
だけで書く
- この場合、
shared_context
の先頭で、毎回send_request (= subject)
を呼ぶ必要はない。
RSpec.describe Api::V1::UsersController, type: :request do
include_context 'api'
describe 'GET /api/v1/users' do
context 'without params' do
let(:expected_response) { ... }
before do
create_list(:user, 2)
get '/api/v1/users'
end
it_behaves_like 'http_status_code_200_with_json'
end
end
end