0
0

More than 1 year has passed since last update.

俺流Request specのフォーマット

Last updated at Posted at 2023-09-20

背景

最近、個人でRuby on Railsを使ってWebサービスのAPIを開発しています。
その際にRSpecを使って主にRequest specを書きました。
spec形式の書き方で試行錯誤したので公開してみます。

俺流Request spec

まずは、コードを共有させていただきます。

組織のCRADを実装したOrganization APIのrequest specです。
rails_helperやメソッドに処理をさせているところもあって、
わかりづらいかもしれませんが動いているコードの一部をほぼそのまま持ってきました。

organizations_request_spec.rb
RSpec.describe 'Organizations', type: :request do
  # 共通のデータ
  let!(:user) { create(:user) }
  let!(:uneditable_user) { create(:user) }
  let!(:organization) { create(:organization) }

  let(:prepare_data) { -> {} }
  let(:headers) { {} }
  let(:params) { {} }

  before do
    prepare_data.call
  end

  describe 'GET /index' do
    before { get organizations_path, headers:, params: }

    context '認証時' do
      let(:headers) { user.create_new_auth_token }

      context 'クエリパラメータが指定されていない場合' do
        it 'リクエストが成功すること' do
          expect(response).to have_http_status(:ok)
        end

        it 'マイボックスが含まれないこと' do
          expect(parsed_response.organizations).not_to include(serialize_organization(user.mybox))
        end

        it 'アクセスできるグループが含まれていること' do
          expect(parsed_response.organizations).to include(serialize_organization(organization))
        end

        it 'アクセスできないグループが含まれないこと' do
          expect(parsed_response.organizations).not_to include(serialize_organization(inaccessible_organization))
        end
      end

      describe 'クエリパラメータを指定' do
        context 'include_myboxパラメータがtrueの場合' do
          let(:params) { { include_mybox: true } }

          it 'リクエストに成功すること' do
            expect(response).to have_http_status(:ok)
          end

          it 'マイボックスが含まれること' do
            expect(parsed_response.organizations).to include(serialize_organization(user.mybox))
          end
        end
      end
    end

    context '未認証時' do
      it '401エラーになること' do
        expect(response).to have_http_status(:unauthorized)
      end
    end
  end

  describe 'GET /show' do
    let(:request_organization) {}
    before { get organization_path(request_organization.name), headers:, params: }

    context '認証時' do
      let(:headers) { user.create_new_auth_token }

      context 'アクセス権限があるグループの場合' do
        let(:request_organization) { organization }

        it 'リクエストが成功すること' do
          expect(response).to have_http_status(:ok)
        end

        it 'リクエストしたグループが返却されること' do
          expect(parsed_response.name).to eq(request_organization.name)
        end
      end

      context 'アクセス権限がないグループの場合' do
        let(:request_organization) { inaccessible_organization }

        it '404エラーになること' do
          expect(response).to have_http_status(:not_found)
        end
      end
    end

    context '未認証時' do
      let(:request_organization) { organization }

      it '401エラーになること' do
        expect(response).to have_http_status(:unauthorized)
      end
    end
  end

目指したもの

describeやcontextで定義した内容をその直下に実装することを目指しました。
普通に書くと、どうしてもAPIのリクエスト(上記のコードだと get organizations_path, headers:, params: )がit付近で呼び出す感じになってしまう。

こんな感じ

好みじゃない書き方.rb
describe 'GET /index' do
    context '認証時' do
      context 'クエリパラメータが指定されていない場合' do
        before { get organizations_path, headers: user.create_new_auth_token }

        it 'リクエストが成功すること' do
          expect(response).to have_http_status(:ok)
        end

これががどうもRSpecらしくないような気がしてしまって
let を駆使して記述してみました。

好みな書き方.rb
  describe 'GET /index' do
    before { get organizations_path, headers:, params: }

    context '認証時' do
      let(:headers) { user.create_new_auth_token }

      context 'クエリパラメータが指定されていない場合' do
        it 'リクエストが成功すること' do
          expect(response).to have_http_status(:ok)
        end

どちらがお好みですか?

実際に書いてみて

今のところ書きやすいし読みやすい。そして、問題も起きていません。
ただ、あまり同じ書き方をしている例が見つけられなかったので、少し不安ではあります。
俺流はだいたい後々後悔するので...(個人開発では、わかっててもやってしまう)

なので、まだオススメはしません。お見せするだけ。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0