ボクココ

個人開発に関するテックブログ

Doorkeeper を使ったRailsのテストをRequest Spec で作る

今回はちょいとマニアック。

問題

APIのテストはController Specではなく、Request Specに書くべきなのだが、DoorkeeperのサンプルコードはController Specで書かれている。こんな感じのコード

describe Api::V1::ProfilesController do
  describe 'GET #index' do
    let(:token) { double :accessible? => true }

    before do
      controller.stub(:doorkeeper_token) { token }
    end

    it 'responds with 200' do
      get :index, :format => :json
      response.status.should eq(200)
    end
  end
end

何も気にせず、そのまま書くとRequest Specの中でcontrollerを呼んじゃっているので、ちゃんとスタブ化されずに401が返ってきてしまう。 てことでこのスタブを違う方法で利用して動作するようにしないといけない。

解決

指定したコントローラのインスタンスのスタブを作るようにする。

  describe 'show user' do
    let(:path) { '/v1/users/' }
 
   it 'should show user' do
      user = FactoryGirl.create(:user, :valid_mail, :same_pass)
      token = double(accessible?: true, resource_owner_id: user._id.to_s)
      V1::UsersController.any_instance.stub(:doorkeeper_token) { token }

      get path
      res = JSON.parse(response.body)
      response.status.should eq(200)
      expect(res["item"]["email"]).to eq("test1@gmail.com")
    end
  end

ポイントはV1::UsersController.any_instance.stub(:doorkeeper_token)の部分。ここでRequest SpecでもControllerをスタブ化することが出来るようになる。

users/show ではcurrent_user の情報を出すだけのコードになっている。 上記のテストはそのcurrent_user を直前でFactoryGirt.createしたものとしてちゃんと取って来れるかっていうテストになる。

ひとこと

FactoryGirl をちゃんとまともに使うようになったけど、これ便利ね。 ちなみに自分のRails API プロジェクトでは versionist ってgemも使ってる。これのジェネレータがなかなか良い。