request specのパターン

request specを書くときに従っているパターンを言語化する。

ファイルパス

1つのエンドポイントに対して1つのテストファイルを用意する。

GET /users GET /users/:id GET /users/:user_id/articles POST /users/:user_id/articles GET /users/:user_id/articles/:id/edit

例えば、上記のエンドポイントに対して以下のファイルを用意する。

  • spec/requests/usersindexspec.rb
  • spec/requests/usersshowspec.rb
  • spec/requests/userarticlesindex_spec.rb
  • spec/requests/userarticlescreate_spec.rb
  • spec/requests/userarticlesedit_spec.rb

以下の背景でこうしている。

  • 関連度が近いファイルが辞書順で近いところに並んでほしい
  • ほとんどの場合、エンドポイントとactionは1対1対応している

ファイルの内容

例えば、GET /users/:id に対するコードは以下のように書く。

``` RSpec.describe "GET /users/:id" do subject do get "/users/#{id}" end

let(:id) do user.id end

let(:user) do FactoryBot.create(:user) end

# ... end ```

describeの中では、以下の順でメソッド呼び出しを行う。

  1. subject
  2. around
  3. before
  4. after
  5. let / let!
  6. shared_context
  7. shared_examples
  8. context

letshared_contextshared_examplesは、第一引数の辞書順で定義する。このとき、letlet!は区別しない。

descriptionsubjectについては、rspec-request_describerの作法に従った書き方でもある。

共通ファイル

例えば、ログインを済ませるコードを共通化したい場合、以下のようなmoduleを定義して利用する。

```

spec/support/myapp/spechelpers/authenticatable.rb

module MyApp module SpecHelpers module Authenticatable extend ::ActiveSupport::Concern

  included do
    shared_context 'with current user' do
      # ...
    end
  end
end

end end ```

トップレベルに奔放に定数を定義せず、そのアプリの名前空間に、ExampleGroupにincludeするmoduleを定義するための名前空間をつくり、そこに定義すること。