Rails テストについて 4 (モデル編)
はじめに
テストに拒否反応があるので、まずは整理したいと思います。
整理していくにつれ、拒否反応がなくなってきたかも・・・
少しづつ記事を書いていきます。
Rails テストについて 1
Rails テストについて 2
Rails テストについて 3
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご助言願います。
specファイルの記述を効率化!!
- factory_botというgemを導入する。
factory_botの導入理由
- 簡単にダミーのインスタンスを作成することができるGem。
- 他のファイルで予め各クラスのインスタンスに定めるプロパティを設定しておく。
- specファイルからメソッドを利用してその通りのインスタンスを作成する。
- 若干、変わります! しかし、これが楽になります。
- imageのみなので、実感はないですが、image以外をもしテストする場合、毎回インスタンスを作成するのは面倒です。なので、factory_botを導入しました!
- 今はパッとしませんが、読み進めていただければ、理解できると思います!
photo_spec.rb
(導入前)
require 'rails_helper'
describe Photo do
describe '#create' do
it "imageがない場合は投稿できないこと" do
photo = Photo.new(image: "")
photo.valid?
expect(photo.errors[:image]).to include("は必要です。")
end
end
end
(導入後)
require 'rails_helper'
describe Photo do
describe '#create' do
it "imageがない場合は投稿できないこと" do
photo = build(:photo, image: nil)
photo.valid?
expect(photo.errors[:image]).to include("は必要です。")
end
end
end
Gemfileに追記
group :development, :test do
#省略
gem 'rspec-rails'
gem 'factory_bot_rails'
end
そして、bundle installです!
factoriesディレクトリの作成と記述
- specディレクトリ直下に「factories」というディレクトリを作成する。
その中に、作成したインスタンスの複数形のファイル名でRubyのファイルを作成する。
上記画像の緑文字ですねー!
そして、コードを記述!
photos.rb
FactoryBot.define do
factory :photo do
image {"image.png"}
end
end
- specファイルの中で特定のメソッドにより簡単にインスタンスを生成したり、DBに保存したりできるようになりました!(今回は imageのみ)
factory_botを導入したことにより、使えるメソッド(以下userインスタンス)
buildメソッド
- 引数にシンボル型で取ったクラス名のインスタンスを、factory_botの記述をもとに作成します。
- 例えば前述のusers.rbが存在する場合、下記2つの変数userの値は同じ値になります。
#factory_botを利用しない場合
user = User.new(nickname: "raiga", email: "[email protected]", password: "00000000", password_confirmation: "00000000")
#factory_botを利用する場合
user = FactoryBot.build(:user)
- 記述量が減りました!!!
createメソッド
- buildとほぼ同じ働きをしますが、createの場合はテスト用のDBに値が保存されます。
- 注意すべき点として、1回のテストが実行され、終了する毎にテスト用のDBの内容がロールバックされます。(保存された値がすべて消去されてしまう)
- 従って、binding.pry等でテストの実行を一時停止しないとテスト用のDBに保存された値をSequel Pro等で確認することはできません。
#createしたインスタンスはDBに保存される
user = FactoryBot.create(:user)
FactoryBotの記述省略
- 記述量は減りましたが、上記「factory_botの導入理由」に記述したコードにはFactoryBotは記述していません。
- 省略方法があります。
- spec/rails_helper.rbを以下のように編集!
rails_helper.rb
#省略
RSpec.configure do |config|
#下記の記述を追加
config.include FactoryBot::Syntax::Methods
#省略
end
- そうすると、FactoryBotの記述がなくても問題ありません。
テストコードの書き方(参考)
- nickname、email、passwordとpassword_confirmationが存在すれば登録できること
- nicknameがない場合は登録できないこと
- emailがない場合は登録できないこと
- passwordがない場合は登録できないこと
- passwordが存在してもpassword_confirmationがない場合は登録できないこと
- nicknameが7文字以上であれば登録できないこと
- nicknameが6文字以下では登録できること
- 重複したemailが存在する場合登録できないこと
- passwordが6文字以上であれば登録できること
- passwordが5文字以下であれば登録できないこと
user_spec.rb
require 'rails_helper'
describe User do
describe '#create' do
# 1
it "nicknameとemail、passwordとpassword_confirmationが存在すれば登録できること" do
user = build(:user)
expect(user).to be_valid
end
# 2
it " nicknameがない場合は登録できないこと" do
user = build(:user, nickname: nil)
user.valid?
expect(user.errors[:nickname]).to include("can't be blank")
end
# 3
it "emailがない場合は登録できないこと" do
user = build(:user, email: nil)
user.valid?
expect(user.errors[:email]).to include("can't be blank")
end
# 4
it "passwordがない場合は登録できないこと" do
user = build(:user, password: nil)
user.valid?
expect(user.errors[:password]).to include("can't be blank")
end
# 5
it "passwordが存在してもpassword_confirmationがない場合は登録できないこと" do
user = build(:user, password_confirmation: "")
user.valid?
expect(user.errors[:password_confirmation]).to include("doesn't match Password")
end
# 6
it " nicknameが7文字以上であれば登録できないこと" do
user = build(:user, nickname: "aaaaaaa")
user.valid?
expect(user.errors[:nickname]).to include("is too long (maximum is 6 characters)")
end
# 7
it "nicknameが6文字以下では登録できること " do
user = build(:user, nickname: "aaaaaa")
expect(user).to be_valid
end
# 8
it " 重複したemailが存在する場合は登録できないこと " do
user = create(:user)
another_user = build(:user, email: user.email)
another_user.valid?
expect(another_user.errors[:email]).to include("has already been taken")
end
# 9
it " passwordが6文字以上であれば登録できること " do
user = build(:user, password: "000000", password_confirmation: "000000")
user.valid?
expect(user).to be_valid
end
# 10
it " passwordが5文字以下であれば登録できないこと " do
user = build(:user, password: "00000", password_confirmation: "00000")
user.valid?
expect(user.errors[:password]).to include("is too short (minimum is 6 characters)")
end
end
end
テスト編、続きます!(次はコントローラーテスト!難しい!)
さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
Author And Source
この問題について(Rails テストについて 4 (モデル編)), 我々は、より多くの情報をここで見つけました https://qiita.com/raigakun/items/e3e4a979541c321f3ec7著者帰属:元の著者の情報は、元の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 .