Rails6】RSpecによるページネーション機能（kaminari）の結合テストの実装

#はじめに
サービスの品質を保つために必要不可欠なテストを実施しております。

今回は、kaminariを使用して、実装したページネーション機能の結合テストを実装し、その実装内容を記事にしていきたいと思います。

#前提
・kaminariというgemを使ってのページネーション機能は実施済み

```Gemfile
gem 'kaminari'
gem 'kaminari-bootstrap'
```

・投稿時の結合テストと同じ、テストファイルにページネーション機能の内容も記述しています。
　投稿時におけるテストコードの記述は以下のURLよりご覧になれます。

https://qiita.com/narimiya/items/45a4561349f1039a9a65

#バージョン
rubyのバージョン　ruby-2.6.5
Railsのバージョン Rails:6.0.0
rspec-rails 4.0.0

#実施したテスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/9c05d402-ab84-1c4d-c7cc-936cc964fb31.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/9e7c2c2d-5f01-fbc7-ab4b-1324d5416238.png)


#ページネーションの画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/e589931d-edb3-4eb1-dbfc-f307f41526c2.png)

#モデルにてページネーションの設定
モデルにて、投稿の表示は1ページ3件までとしています。

```app/models/definition.rb
# 〜省略〜

# 最近作成されたユーザーから表示
default_scope -> { order(created_at: :desc) }
# 一度に表示する投稿数
paginates_per 3

# 〜省略〜
```


#definitionsテーブルのカラムの紹介

```xxx_create_definitions.rb
class CreateDefinitions < ActiveRecord::Migration[6.0]
  def change
    create_table :definitions do |t|
      t.text       :title,          null: false
      t.text       :body,           null: false
      t.references :user,           foreign_key: true
      t.timestamps
    end
  end
end
```

#モデル内のバリデーション

```app/models/definition.rb
class Definition < ApplicationRecord
  belongs_to :user
  has_many :answers, dependent: :destroy
  has_many :reviews, dependent: :destroy
  has_many :notifications, dependent: :destroy
  has_many :likes, dependent: :destroy

  validates :title, presence: true
  validates :body, presence: true

# 〜省略〜
```


#FactoryBotの内訳

```spec/factories/definitions.rb
FactoryBot.define do
  factory :definition do
    title                        {Faker::Lorem.sentence}
    body                         {Faker::Lorem.sentence}
    association :user
  end
end
```

#サポートモジュール
新規投稿する際の記述をモジュール化しています。

```spec/support/definition_up_support.rb
module DefinitionUpSupport
  def definition_up(definition_title, definition_body)
 
    # 新規投稿ページへのリンクがあることを確認する
    expect(page).to have_content('投稿')

    # 投稿作成ページに移動する
    visit new_definition_path

    # フォームに情報を入力する
    fill_in 'definition[title]', with: definition_title
    fill_in 'definition[body]', with: definition_body

    # 送信するとDefinitionモデルのカウントが1上がることを確認する
    expect{
      find('input[name="commit"]').click
    }.to change { Definition.count }.by(1)

    # 投稿完了ページに遷移することを確認する
    expect(current_path).to eq(root_path)
  end
end
```

ページ遷移して投稿の存在を確認する記述をモジュール化しています。

```spec/support/page_up_support.rb
module PageUpSupport
  def page_up(definition)
    # ページ遷移していることを確認する
    expect(current_path).to eq(root_path)

    # 投稿があることを確認する
    expect(page).to have_no_content("#{definition.title}")
  end
end
```

#テストコードの内容

```spec/system/definitions_spec.rb

#投稿における結合テストの記述は省略

RSpec.describe 'ページネーションについて', type: :system do
    before do
      @definition = FactoryBot.create(:definition)
      @definition_title = Faker::Lorem.sentence
      @definition_body = Faker::Lorem.sentence
    end
      context 'ページネーションでページ遷移ができるとき' do
          it 'ログインしたユーザーはページネーションでページ遷移ができる' do
          # definitionを投稿したユーザーでログインする
          sign_in(@definition.user)
  
          # ①新規投稿する(投稿は3件表示のため4つ投稿を行う)
          definition_up(@definition_title, @definition_body)

          # ②新規投稿する(投稿は3件表示のため4つ投稿を行う)
          definition_up(@definition_title, @definition_body)

          # ③新規投稿する(投稿は3件表示のため4つ投稿を行う)
          definition_up(@definition_title, @definition_body)

          # ④新規投稿する(投稿は3件表示のため4つ投稿を行う)
          definition_up(@definition_title, @definition_body)
        
          # 投稿ページに移動する
          visit root_path(anchor:"ethics")

          # ページがあることを確認
          expect(page).to have_css(".page-link")

          # ページネーション'2'のボタンをクリックし、次ページへと行く
          expect{ find_link('2', rel="next").click }

          # ページ遷移していることを確認し、投稿があることを確認する
          page_up(@definition)

          # ページネーション'1'のボタンをクリックし前ページへと行く
          expect{ find_link('1', rel="prev").click }

          # ページ遷移していることを確認し、投稿があることを確認する
          page_up(@definition)

          # ページネーションボタン'最後'のボタンをクリックし、最後のページへと行く
          expect{ find_link('最後', ".page-link").click }

          # ページ遷移していることを確認し、投稿があることを確認する
          page_up(@definition)
           
          # ページネーションボタン'最初'のボタンをクリックし、最初のページへと行く
          expect{ find_link('最初', ".page-link").click }

          # ページ遷移していることを確認し、投稿があることを確認する
          page_up(@definition)
       end
    end
end

```

以上です。