【Rails6】RSpecによるレビュー機能の結合テストの実装
はじめに
サービスの品質を保つために必要不可欠なテストを実施しております。
今回はレビュー機能の結合テストを実装し、その実装内容を記事にしていきたいと思います。
前提
・レビュー機能は実装済み
・Review(レビュー)モデルの単体テストは実施済み
※完了されていない方や単体テストと並行してご覧になられたい方は、以下のReviewモデルの単体テストについての記事をご参考ください。
バージョン
rubyのバージョン ruby-2.6.5
Railsのバージョン Rails:6.0.0
rspec-rails 4.0.0
実施したテスト
レビュー画面
reviewsテーブルのカラムの紹介
xxx_create_reviews.rb
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :reviews do |t|
t.string :content
t.integer :score
t.references :user, foreign_key: true
t.references :definition, foreign_key: true
t.timestamps
end
end
end
モデル内のバリデーション
app/models/review.rb
class Review < ApplicationRecord
belongs_to :user
belongs_to :definition
validates :user_id, presence: true
validates :definition_id, presence: true
validates :score, presence: true
validates_uniqueness_of :definition_id, scope: :user_id
end
FactoryBotの内訳
spec/factories/reviews.rb
FactoryBot.define do
factory :review do
association :definition
association :user
content {Faker::Lorem.word}
score {'3'}
end
end
サポートモジュール
spec/support/review_up_support.rb
module ReviewUpSupport
def review_up(review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# レビューの存在の確認
expect(page).to have_selector '#star1'
expect(page).to have_selector '#star2'
expect(page).to have_selector '#star3'
expect(page).to have_selector '#star4'
expect(page).to have_selector '#star5'
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが1上がることを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(1)
end
end
テストコードの内容
spec/system/reviews_spec.rb
require 'rails_helper'
RSpec.describe "Reviews", type: :system, js: true do
before do
@definition = FactoryBot.create(:definition)
@review = FactoryBot.create(:review)
end
describe '#create,#destroy' do
context 'レビューができるとき' do
it 'ユーザーが投稿に対してレビューができる' do
# ログインする
sign_in(@definition.user)
#新規レビューを作成する
review_up(@review)
# # レビュー詳細ページに遷移する
visit definition_reviews_path(@definition)
# レビュー詳細ページにてレビューした投稿があることを確認する
expect(page).to have_content(@review.score)
expect(page).to have_content(@review.content)
end
end
context 'レビューができないとき' do
it 'ユーザーが投稿に対してレビューをすでにしており、レビューができない' do
# ログインする
sign_in(@definition.user)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
#新規レビューを作成する
review_up(@review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: @review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが上がらないことを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(0)
# レビューページへ戻されることを確認する
expect(current_path).to eq(definition_reviews_path(@definition))
end
end
end
end
補足説明
#starについて
xxx_create_reviews.rb
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :reviews do |t|
t.string :content
t.integer :score
t.references :user, foreign_key: true
t.references :definition, foreign_key: true
t.timestamps
end
end
end
app/models/review.rb
class Review < ApplicationRecord
belongs_to :user
belongs_to :definition
validates :user_id, presence: true
validates :definition_id, presence: true
validates :score, presence: true
validates_uniqueness_of :definition_id, scope: :user_id
end
FactoryBotの内訳
spec/factories/reviews.rb
FactoryBot.define do
factory :review do
association :definition
association :user
content {Faker::Lorem.word}
score {'3'}
end
end
サポートモジュール
spec/support/review_up_support.rb
module ReviewUpSupport
def review_up(review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# レビューの存在の確認
expect(page).to have_selector '#star1'
expect(page).to have_selector '#star2'
expect(page).to have_selector '#star3'
expect(page).to have_selector '#star4'
expect(page).to have_selector '#star5'
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが1上がることを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(1)
end
end
テストコードの内容
spec/system/reviews_spec.rb
require 'rails_helper'
RSpec.describe "Reviews", type: :system, js: true do
before do
@definition = FactoryBot.create(:definition)
@review = FactoryBot.create(:review)
end
describe '#create,#destroy' do
context 'レビューができるとき' do
it 'ユーザーが投稿に対してレビューができる' do
# ログインする
sign_in(@definition.user)
#新規レビューを作成する
review_up(@review)
# # レビュー詳細ページに遷移する
visit definition_reviews_path(@definition)
# レビュー詳細ページにてレビューした投稿があることを確認する
expect(page).to have_content(@review.score)
expect(page).to have_content(@review.content)
end
end
context 'レビューができないとき' do
it 'ユーザーが投稿に対してレビューをすでにしており、レビューができない' do
# ログインする
sign_in(@definition.user)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
#新規レビューを作成する
review_up(@review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: @review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが上がらないことを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(0)
# レビューページへ戻されることを確認する
expect(current_path).to eq(definition_reviews_path(@definition))
end
end
end
end
補足説明
#starについて
spec/factories/reviews.rb
FactoryBot.define do
factory :review do
association :definition
association :user
content {Faker::Lorem.word}
score {'3'}
end
end
spec/support/review_up_support.rb
module ReviewUpSupport
def review_up(review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# レビューの存在の確認
expect(page).to have_selector '#star1'
expect(page).to have_selector '#star2'
expect(page).to have_selector '#star3'
expect(page).to have_selector '#star4'
expect(page).to have_selector '#star5'
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが1上がることを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(1)
end
end
テストコードの内容
spec/system/reviews_spec.rb
require 'rails_helper'
RSpec.describe "Reviews", type: :system, js: true do
before do
@definition = FactoryBot.create(:definition)
@review = FactoryBot.create(:review)
end
describe '#create,#destroy' do
context 'レビューができるとき' do
it 'ユーザーが投稿に対してレビューができる' do
# ログインする
sign_in(@definition.user)
#新規レビューを作成する
review_up(@review)
# # レビュー詳細ページに遷移する
visit definition_reviews_path(@definition)
# レビュー詳細ページにてレビューした投稿があることを確認する
expect(page).to have_content(@review.score)
expect(page).to have_content(@review.content)
end
end
context 'レビューができないとき' do
it 'ユーザーが投稿に対してレビューをすでにしており、レビューができない' do
# ログインする
sign_in(@definition.user)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
#新規レビューを作成する
review_up(@review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: @review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが上がらないことを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(0)
# レビューページへ戻されることを確認する
expect(current_path).to eq(definition_reviews_path(@definition))
end
end
end
end
補足説明
#starについて
spec/system/reviews_spec.rb
require 'rails_helper'
RSpec.describe "Reviews", type: :system, js: true do
before do
@definition = FactoryBot.create(:definition)
@review = FactoryBot.create(:review)
end
describe '#create,#destroy' do
context 'レビューができるとき' do
it 'ユーザーが投稿に対してレビューができる' do
# ログインする
sign_in(@definition.user)
#新規レビューを作成する
review_up(@review)
# # レビュー詳細ページに遷移する
visit definition_reviews_path(@definition)
# レビュー詳細ページにてレビューした投稿があることを確認する
expect(page).to have_content(@review.score)
expect(page).to have_content(@review.content)
end
end
context 'レビューができないとき' do
it 'ユーザーが投稿に対してレビューをすでにしており、レビューができない' do
# ログインする
sign_in(@definition.user)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
#新規レビューを作成する
review_up(@review)
# レビュー作成ページに遷移する
visit new_definition_review_path(@definition)
# 星マークにカーソルを合わた場所でクリックする(今回は3段階)
expect(find('#star3').hover.click)
# レビューのコメントに情報を入力する
fill_in 'review[content]', with: @review.content
# レビューのコメントを送信すると、Reviewモデルのカウントが上がらないことを確認する
expect{
find('input[name="commit"]').click
}.to change { Review.count }.by(0)
# レビューページへ戻されることを確認する
expect(current_path).to eq(definition_reviews_path(@definition))
end
end
end
end
#starについて
星マークを記述しているview内のidであり、今回は5つあります。
テストの関係上idを区別する必要があったため番付しています。
app/views/reviews/index.html.erb
# 〜省略〜
<span class="fa fa-star-o" id="star1"></span>
<span class="fa fa-star-o" id="star2"></span>
<span class="fa fa-star-o" id="star3"></span>
<span class="fa fa-star-o" id="star4"></span>
<span class="fa fa-star-o" id="star5"></span>
# 〜省略〜
'#'を文頭につけることでidを指し示すことができます。
異常系のReview.countについて
モデル内にuniqunessのバリデーションをかけており、レビューは1回しかできない仕様にしています。
app/models/review.rb
validates_uniqueness_of :definition_id, scope: :user_id
したがって一度レビューし、再度レビューしてもレビューカウントは上がらず0のままを証明できれば、レビューができていないことが言えます。
以上です。
Author And Source
この問題について(【Rails6】RSpecによるレビュー機能の結合テストの実装), 我々は、より多くの情報をここで見つけました https://qiita.com/narimiya/items/90500f984afd74b97f91著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .