Grape::Entityを継承したEntityクラスをRSpecでテストする

Rails+grapeで RESTful APIを作るとき、APIのレスポンスデータを制御するためのgrape-entityを合わせて使うケースがあると思います。

その場合、Grape::Entityクラスを継承したEntityクラスを作成することになると思いますが、 このEntityクラスをRSpecを使ってテストする場合の方法についてメモを残しておきます。


Entityクラス

ここでは、例として次のようなクラスを考えてみます。

class UserEntity < Grape::Entity
  expose :id
  expose :email
  expose :name
  expose :created_at
  expose :updated_at
end

RSpec

Grape::Entityは、representというクラスメソッドが定義されており、 Grapeを使ったAPIの処理の中で、

present @user, with: UserEntity

とした場合、このrepresentが呼ばれます。 なので、representメソッドを使うことで、Entityクラスが生成する応答データを取得することができそうです。

実際、上記のEntityクラスをRSpecを使ってテストする場合、 次のようなspecを書いてテストすることができます。

require 'rails_helper'

RSpec.describe UserEntity do
  subject { described_class.represent(user).to_json }

  let(:user) { FactoryGirl.create(:user) }

  it 'exposes id.' do
    expect(subject['id']).to eq user.id
  end

  it 'exposes email.' do
    expect(subject['email']).to eq user.email
  end

  # 以下、省略
end

ここでは、jsonを返すAPIを前提として、to_jsonを実行した結果をテストしていますが、 APIのフォーマットによっては変更すべきところですが、ひとまず、この方法でEntityクラスの独立したテストが書くことができます。

Entityクラスのテストを書くことで個々のAPIのテストでは、応答データの詳細のテストを書く必要がなくなる、ってのはいい作用かなと思います。