rspecをshared_examples_forでまとめる

rspecで共通項があった場合、shared_examples_forでまとめることができます。

使い方

下記のようなmoduleがあったとします。

app/models/concerns/body_validators.rb

module BodyValidators
  extend ActiveSupport::Concern

  included do
    validates :body, presence: true,
                     length: { maximum: 200 }
  end
end

app/models/post.rb

class Post < ActiveRecord::Base
  include BodyValidators
end

app/models/comment.rb

class Comment < ActiveRecord::Base
  include BodyValidators
end

この二つは同じなので、共通して処理を行いたいです。

supportでshared_examples_forをincludeできるようにします。

spec/support/models/concerns/body_validators_spec.rb

require 'rails_helper'

shared_examples_for 'body validation' do
  describe 'body is' do
    it 'not empty' do
      body.body = nil
      expect(body).not_to be_valid
    end

    it 'maximum 200charcters' do
      maximum_charcters = 'a' * 500
      body.body = maximum_charcters
      expect(body).not_to be_valid
    end
  end
end

it_behaves_likeからは引数を渡せるので、引数を渡します。

spec/models/post.rb

require 'rails_helper'

RSpec.describe Comment, type: :model do
  context 'validation' do
    it_behaves_like 'body validation' do
      let(:body) { build(:comment) }
    end
  end
end

これで共通の処理を行うことができます。

まとめ

shared_examples_forを使えば、テストのリファクタリングができます。

spec/models/comment.rb

require 'rails_helper'

RSpec.describe Comment, type: :model do
  context 'validation' do
    it_behaves_like 'body validation' do
      let(:body) { build(:comment) }
    end
  end
end