【Rspec】requests spec·컨트롤러의 테스트에 대해 ~admin 유저 작성이나 edit 액션의 테스트~

11570 단어 RSpec루비Rails

requests spec 컨트롤러 테스트에 대한 이야기



모델과 결합 테스트는 문제 없게 끝났고, 컨트롤러의 테스트에 대해 이것저것 조사하고 있었지만 좀처럼 자신에게 이해할 수 있는 것이 없고, 곤란하고 있었습니다.
공개되고 있는 GitHub의 코드를 봐도 컨트롤러의 테스트 코드를 하고 있는 사람이 적었다고 하는 것도 하나의 요인입니다만, 시행착오해 어떻게든 완성했습니다.
솔직히 이것으로 좋은지 조금 모르는 부분도 있으므로, 만약 지견이 있는 분이 이 기사를 봐 주시면 코멘트 받을 수 있으면 기쁩니다.

admin 사용자 생성에 어려움



DB에 admin 컬럼을 만들고 true 또는 false로 판별하고 있습니다.
FactoryBot에서 사용자를 생성하기 위해 작성한 코드는 다음과 같습니다.

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              { '野比のび太' }
    sequence(:email)      { |n| "tester#{n}@example.com" }
    password              { 'q11111' }
    password_confirmation { password }
    profile               { 'なんとかしてよドラえもん' }
    admin                 { false }    ⬅️一般ユーザー
  end

  factory :admin_user do
    nickname              { 'ドラえもん' }
    sequence(:email)      { |n| "tester#{n}@example.com" }
    password              { 'a11111' }
    password_confirmation { password }
    profile               { 'いつまでも子供じゃないんだよしっかりしろよ' }
    admin                 { true }     ⬅️adminユーザー
  end
end

그리고 users_spec.rb에는 다음과 같이 기술.

spec/requests/users_spec.rb

RSpec.describe UsersController, type: :request do
  let(:user) { FactoryBot.create(:user) }
  let(:admin_user) { FactoryBot.create(:user, admin: true) }
 #let(:admin_user) { FactoryBot.create(:admin_user) }⬅️この書き方でもダメでした

이것으로 admin 유저가 작성될 것이라고 생각하고 있었습니다만 binding.pry 로 멈추어 내용을 보면 admin_user 가 작성되어 있지 않았습니다.
여러가지 쓰는 방법을 바꾸어 보았는데, let 를 사용하지 않고 before do 로 하면 잘 되었습니다.

spec/requests/users_spec.rb
RSpec.describe UsersController, type: :request do
  before do
    @user = FactoryBot.create(:user)
    @admin_user = FactoryBot.create(:user, admin: true)
   #@admin_user = FactoryBot.create(:admin_user)⬅️この書き方でもダメでした
  end



일단 이것으로 일반 사용자와 admin 사용자를 나눌 수 있게 되었습니다.

edit 액션 테스트에서 어려움



컨트롤러의 테스트를 하기에 우선 곤란한 것이 edit 액션의 테스트였습니다.authenticate_user!를 사용하기 때문에 컨트롤러 테스트를 실행할 때,
"로그인하지 않은 사용자"로 간주되어 리디렉션됩니다.
요청이 정상적인 응답이 아니면 테스트 항목expect(response.status).to eq 200여기 200이 302가 되어 버립니다.

또, 편집할 수 있을 때와 할 수 없을 때, 양쪽 모두의 테스트를 해야 하기 때문에, 컨트롤러의 테스트 코드상에서 로그인을 시킬 수 있으면 정상적인 반환값을 얻을 수 있다고 생각했습니다.

devise 메서드를 테스트 코드에서도 사용할 수 있도록하려면



테스트 코드상에서 로그인시키는 메소드로서 결합 테스트 코드시에 사용하고 있던 module로 해 보았는데, 잘 작동하지 않았습니다.
조사한 결과, 컨트롤러의 테스트에서는 devise의 메소드를 사용할 수 있다는 것이었기 때문에 그쪽으로 전환했습니다.

spec/rails_helper.rb
RSpec.configure do |config|
  #deviseのsign_inメソッドが使えるようになる
  config.include Devise::Test::IntegrationHelpers, type: :request
end

이제 sign_in라는 메서드를 사용할 수 있습니다.
자신의 경우는 @user 라고 정의하고 있으므로 그대로 사용합니다.

spec/requests/users_spec.rb
require 'rails_helper'
RSpec.describe UsersController, type: :request do
  before do
    @user = FactoryBot.create(:user)
  end

  describe 'GET #edit' do
    context 'userがログインしているとき' do
      before do
        sign_in @user  ⬅️ここでログイン
      end
      it 'editアクションにリクエストすると正常にレスポンスが返ってくる' do
        get edit_user_path(@user)
        expect(response.status).to eq 200  ⬅️編集画面に遷移できている
      end
      it "editアクションにリクエストするとレスポンスに登録済みuserの名前が存在する" do 
        get edit_user_path(@user)
        expect(response.body).to include @user.nickname
      end
      it "editアクションにリクエストするとレスポンスに登録済みuserのプロフィールが存在する" do 
        get edit_user_path(@user)
        expect(response.body).to include @user.profile
      end
    end

    context 'userがログインしていないとき' do
      it 'editアクションにリクエストすると正常にレスポンスが返ってくる' do
        get edit_user_path(@user)
        expect(response.status).to eq 302  ⬅️トップページにリダイレクトしている
      end
    end
  end
end


이것으로 잘 작동했습니다.
admin_user로 만들려면 before do에서 @admin_user를 정의하고,sign_in @admin_user 로 다른 컨트롤러에서도 문제 없이 처리할 수 있었습니다.
테스트 코드를 사용하면 응용 프로그램 사양을 잘 이해할 수 있다고 말하지만 이유를 잘 알았습니다.
세세한 곳을 깨닫거나 사양 그 자체를 처음부터 검토하는 결과가 되어 이해가 깊어졌다고 실감할 수 있었습니다.

참고로했습니다.



🍑🏻‍♀️
[Rails] Request Spec에서 로그인 실시

고마워요.

좋은 웹페이지 즐겨찾기