LoginSignup
0
0

More than 1 year has passed since last update.

[Rails] Rspec ポートフォリオに実装したrequest spec

Posted at

はじめに

ポートフォリオに実際に実装したrequest specの部分です。
テストコードについては勉強したけどテストコードを実際に書く時にどんなことをテストすればいいか分からないと思ったのでそういった人の参考になれば嬉しいです。
テストしたのはCRUD機能部分です。

index

Controller

with_attached_eyecatchはactive storageでN+1が起きないするためのメソッドです。

app/controllers/event_controller.rb
def index
  @events = Event.with_attached_eyecatch.latest
end

request spec

subjectを使うことでリクエストを共通化しています。

spec/requests/events_spec.rb
describe 'GET #index' do
  subject { get(events_path) }
  context 'イベントが存在する場合' do
    let!(:event) { create(:event, user_id: user.id) }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(200)
    end

    it 'name が表示されている' do
      subject
      expect(response.body).to include event.name
    end
  end
end

show

Controller

app/controllers/event_controller.rb
def show
  @event = Event.find(params[:id])
end

request spec

spec/requests/events_spec.rb
describe 'GET #show' do
  subject { get(event_path(event.id)) }

  context 'イベントが存在する場合' do
    let(:event) { create(:event, user_id: user.id) }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(200)
    end

    it 'name が表示されている' do
      subject
      expect(response.body).to include event.name
    end
  end
end

new

Controller

app/controllers/event_controller.rb
def new
  @event = current_user.events.build
end

request spec

spec/requests/events_spec.rb
describe 'GET #new' do
  subject { get(new_event_path) }

  it 'リクエストが成功する' do
    subject
    expect(response).to have_http_status(200)
  end
end

post

Controller

app/controllers/event_controller.rb
def create
  @event = current_user.events.build(event_params)
  if @event.save
    redirect_to event_path(@event), notice: '作成しました'
  else
    flash.now[:error] = '作成に失敗しました'
    render :new
  end
end

request spec

パラメーターが必要なのでパラメーターが正常のテストと異常のテストの両方をテストします。
異常系のテストはバリデーションエラーが出ることをテストしています。

spec/requests/events_spec.rb
describe 'POST #create' do
  subject { post(events_path, params: params) }

  context 'パラメータが正常な場合' do
    let(:params) { { event: attributes_for(:event) } }

    it '投稿が保存される' do
      expect { subject }.to change { Event.count }.by(1)
    end

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(302)
    end

    it 'イベント一覧ページにリダイレクトされる' do
      subject
      expect(response).to redirect_to('http://www.example.com/events?locale=ja')
    end
  end

  context 'パラメータが異常な場合' do
    let(:params) { { event: attributes_for(:event, :invalid) } }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(200)
    end

    it '投稿が保存されない' do
      expect { subject }.not_to change(Event, :count)
    end

    it 'イベント投稿ページがレンダリングされる' do
      subject
      expect(response.body).to include I18n.t('events.form.event-post')
    end
  end
end

edit

Controller

app/controllers/event_controller.rb
def edit
  @event = current_user.events.find(params[:id])
end

request spec

spec/requests/events_spec.rb
describe 'GET #edit' do
  subject { get(edit_event_path(event_id)) }

  context 'イベントが存在する場合' do
    let(:event) { create(:event, user_id: user.id) }
    let(:event_id) { event.id }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(200)
    end

    it 'name が表示されている' do
      subject
      expect(response.body).to include event.name
    end
  end
end

update

Controller

app/controllers/event_controller.rb
def update
  @event = current_user.events.find(params[:id])
  if @event.update(event_params)
    redirect_to event_path(@event), notice: '更新しました'
  else
    flash.now[:error] = '更新に失敗しました'
    render :edit
  end
end

request spec

パラメーターが必要なので異常系のテストも必要。
createとの違いはデータの更新ができていることreloadメソッドを使うことで更新した値のテストが可能。

spec/requests/events_spec.rb
describe 'PATCH #update' do
  subject { patch(event_path(event.id), params: params) }
  let(:event) { create(:event, user_id: user.id) }

  context 'パラメーターが正常な場合' do
    let(:params) { { event: attributes_for(:event) } }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(302)
    end

    it 'name が更新される' do
      origin_name = event.name
      new_name = params[:event][:name]
      expect { subject }.to change { event.reload.name }.from(origin_name).to(new_name)
    end
  end

  context 'パラメータが異常なとき' do
    let(:params) { { event: attributes_for(:event, :invalid) } }

    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(200)
    end

    it 'name が更新されない' do
      expect { subject }.not_to change(event.reload, :name)
    end

    it 'イベント編集ページがレンダリングされる' do
      subject
      expect(response.body).to include I18n.t('events.form.event-edit')
    end
  end
end

destroy

Controller

app/controllers/event_controller.rb
def destroy
  event = current_user.events.find(params[:id])
  event.destroy!
  redirect_to events_path, notice: '削除しました'
end

request spec

let!とすることで各テストの最初に実行される。

spec/requests/events_spec.rb
describe 'DELETE #destroy' do
  subject { delete(event_path(event.id)) }
  let!(:event) { create(:event, user_id: user.id) }

  context 'パラメータが正常な場合' do
    it 'リクエストが成功する' do
      subject
      expect(response).to have_http_status(302)
    end

    it 'イベントが削除される' do
      expect { subject }.to change(Event, :count).by(-1)
    end

    it 'イベント一覧にリダイレクトすること' do
      subject
      expect(response).to redirect_to('http://www.example.com/events?locale=ja')
    end
  end
end

以上です。
最後はsystem spec!

0
0
0

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