0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

多対多(グループとユーザー)のRspecで躓いた箇所の備忘録

Last updated at Posted at 2022-10-07

概要

ポートフォリオ作成で、多対多のモデルが絡むRspecを書いていたときに躓きました。その時の解決策を備忘録として書き留めています。

こちらの記事を参考にさせていただきました。

開発環境

  • OS:Amazon Linux2
  • Rails 6.1.6.1

背景

マイページで、「自分が参加しているグループの一覧が表示される」というテストを書く際、「グループに所属しているユーザーの数」という記述をする必要がありました。グループとユーザーは、下記に示すように多対多となっており、中間テーブルを考慮した記述をする必要がありました。
pf_ER-ページ5 drawio

解決策

まずは、group_spec.rbのテスト部分に、Userモデルとのアソシエーションを記述します。

spec/models/group_spec.rb
  #省略
  describe 'アソシエーションのテスト' do
    context 'Userモデルとの関係' do
      it '1:Nとなっている' do
        expect(Group.reflect_on_association(:users).macro).to eq :has_many
      end
    end
  end
  #省略

同様に、user_spec.rbのテスト部分にも、Groupモデルとのアソシエーションを記述します。

spec/models/user_spec.rb
  #省略
  describe 'アソシエーションのテスト' do
    context 'Groupモデルとの関係' do
      it '1:Nとなっている' do
        expect(User.reflect_on_association(:groups).macro).to eq :has_many
      end
    end
  end
  #省略

続いて、userのファクトリを作成します(多対多のテストでは、ここが重要みたいです。)

spec/factories/user.rb
  #省略
    trait :user_with_groups do
      #userが作られるとき、自動的にuser.groups(userに紐づいたgroups、すなわちgroup_user)を作るということ
      after(:build) do |user|
        user.groups << build(:group)
      end
    end
  #省略

上記の記述をすることで、テスト実行中にuserが作成されたとき、そのuserに紐づいたgroupも自動的に作成することができるようになるようです!

準備が整ったので、コントローラのテストコードの方を書いていきます!

spec/system/after_login_spec.rb
describe 'ユーザーログイン後のテスト' do
  #省略
  #:user_with_groupsは、先ほどfactories/user.rbに記述。ここで記述することで、userが作成された際、userに紐づいたgroup(id: 1)が作成される。
  let(:user) { create(:user, :user_with_groups) } 
  let!(:other_user) { create(:user) }
  #ここで、Group.firstとしているのは、今回のテストで使用するのは、先ほど:user_with_groupsで作成されたuserに紐づいたgroupであるため。
  let!(:group) { Group.first }
  #省略

  before do
    visit new_user_session_path
    fill_in 'user[email]', with: user.email
    fill_in 'user[password]', with: user.password
    click_button 'Log in'
  end
  #省略
  describe '自分のマイページのテスト' do
    before do
      visit user_path(user)
    end

    #省略

    context 'サイドバーの確認' do
      #省略
      it '自分が参加中のグループ一覧が表示される' do
        #「id=1のgroup.nameを押した遷移先がグループの詳細ページである」
        expect(page).to have_link group.name, href: group_path(group)
        #今回通したかったテスト。「id=1のgroupに紐づいたusersの数が表示される」
        expect(page).to have_content group.users.count
      end
      #省略
    end
  end
#省略
  expect(page).to have_content group.users.count

こちらのgroup.usersは、アソシエーションで中間テーブルのgroup_usersテーブルを介した記述なので、上記のuserのファクトリに記述を行い、group_userも作成する必要があるということなのですね。

終わりに

これで無事にRspecが通りました!今後Rspecがスラスラ書けるように学習していきます!今は主にRubyとrailsを学習しているので、他に学んだことも投稿させていただきます!

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?