#はじめに
みなさん単体テストは好きですか??
私は苦手です。。。。
多分苦手な方も多いと思うので、今回はモデルの単体テストの書き方について紹介できればいいかなと思います。
私も未熟なので、参考程度にしてください。おねがいします。。
#1.Gemfile
はじめにgemfileにrspecを導入していきます。
今回はfactory_botも使うので、以下のようにgemfileに記述していきましょう。
group :development, :test do
gem 'rspec-rails', '~> 3.8'
gem 'factory_bot_rails', '~> 5.0'
end
bundle installも忘れずに!
$ bundle install
#2.RSpecの設定
ターミナルで以下のコマンドを記述。
specというディレクトリが生成されます。
$ rails g rspec:install
.rspecに以下を記述
--format documentation
テスト用のDBを最新の構成にする
$ rails db:migrate:reset RAILS_ENV=test
#3.モデルを作成し単体テストを書いていこう
まずはテストモデルを生成します。
$ rails generate rspec:model モデル名
それではfactory_botを使ってモデルにテストデータを予め準備します。
spec/factories/モデル名.rbファイルを作成しましょう。
ファイルの中身の模範は以下のようです。
FactoryBot.define do
factory :モデル名 do
カラム名 {"仮の値"}
end
end
実際に書くとこんな感じ。
FactoryBot.define do
factory :product do
name {Faker::Games::Zelda.item}
infomation {Faker::Games::Zelda.game}
category_id {"1"}
brand {Faker::Games::Zelda.location}
status_id {"1"}
delivery_id {"1"}
area_id {"1"}
day_id {"1"}
price {Faker::Number.number(digits: 4)}
situation {"1"}
user
end
end
続いて、factory_botの情報を使ってテストコードを書いていきます。
spec/models/モデル名_spec.rbファイルを作成しましょう。
ファイルの中身の模範はこんな感じ。
require 'rails_helper'
describe モデル名 do
describe '#メソッド名' do
context 'グループ分けの説明' do
it 'テストの説明' do
テスト内容
end
end
end
end
実際はこんな感じ。
factory_botを使用しているので、記述量が減って簡単にかけます!
require 'rails_helper'
describe Product do
describe '#create' do
context '出品できる場合' do
it "productとproduct_imageがある場合は保存できること" do
expect(build(:product, product_images: [build(:product_image)])).to be_valid
end
end
context '出品できない場合' do
it "product_imageがない場合は保存できないこと" do
product = build(:product)
product.valid?
expect(product.errors[:product_images]).to include("can't be blank")
end
it "nameがない場合は保存できないこと" do
product = build(:product, name: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:name]).to include("can't be blank")
end
it "infomationがない場合は保存できないこと" do
product = build(:product, infomation: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:infomation]).to include("can't be blank")
end
it "category_idがない場合は保存できないこと" do
product = build(:product, category_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:category_id]).to include()
end
it "status_idがない場合は保存できないこと" do
product = build(:product, status_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:status_id]).to include()
end
it "delivery_idがない場合は保存できないこと" do
product = build(:product, delivery_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:delivery_id]).to include()
end
it "area_idがない場合は保存できないこと" do
product = build(:product, area_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:area_id]).to include()
end
it "day_idがない場合は保存できないこと" do
product = build(:product, day_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:day_id]).to include()
end
it "priceがない場合は保存できないこと" do
product = build(:product, price: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:price]).to include()
end
it "priceが300以下の場合は保存できないこと" do
product = build(:product, price: "299", product_images: [build(:product_image)])
product.valid?
expect(product.errors[:price]).to include()
end
it "priceが9,999,999以上の場合は保存できないこと" do
product = build(:product, price: "10000000", product_images: [build(:product_image)])
product.valid?
expect(product.errors[:price]).to include()
end
it "user_idがない場合は保存できないこと" do
product = build(:product, user_id: nil, product_images: [build(:product_image)])
product.valid?
expect(product.errors[:user_id]).to include()
end
end
end
end
最後に以下のコマンドをターミナルで実行し、テストがうまくいっているか確認です!
$ bundle exec rspec spec/models/モデル名_spec.rb
以上です!