Rails 基礎 Part 04 -- index の単体テストを RSpec と FactoryBot で作る
kaede
Posted on May 21, 2023
why
コーチングを受けて、テストピラミッドを学んだ。
これにより、単体テストを絶対に書くべきだと考えた。
単体テストを全て書くためには、スピードを上げる必要があると考えた。
テストを作るスピードが遅ければ、テストだけどんどん別チケットになってたまってしまうからだ。
テストを作るスピードを上げるために、プライベートで一から作ってみることにした。
テストピラミッドについて
テストピラミッドは、下記の図のようになっている。
/\
/ \
/ UI \
/ テスト \
/---------\
/ 統合テスト \
/-------------\
/ ユニットテスト \
/------------------\
参考は下記 URL
https://thinkit.co.jp/article/13346
今回の作業に必要なもの
- Controller の実装本体。index メソッド。前回の記事で作成ずみ
- Rspec ライブラリ。Rails にビルドインされている。
- FactoryBot のライブラリ。
- FactoryBot でのテストデータ生成用のファクトリー定義ファイル
- RSpec と ファクトリー定義ファイル を使った単体テストのファイル
ファクトリーとは?
データを生成する場所のこと。
現実世界の具体例で考えてみよう。
僕らはコンビニで食べ物を買う。
しかしコンビニでは基本的に物を製造しない。
製品は別の場所、工場でで作られる。
それからコンビニに運ばれて売られる。
これをデータに置き換えよう。
データを生成する「工場」がまさに「ファクトリー」。
そして今回、このファクトリーを単体テストフレームワークである RSpec で使用する。
前回作った API の GET から UT を作っていく
Gemfile でライブラリのインストール
単体テスト専用のデータを作るため、FactoryBot
というライブラリをインストールする。
Gemfile
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri mingw x64_mingw ]
gem 'rspec-rails', '~> 6.0.0'
gem 'factory_bot_rails'
end
これで development or test でのみ動く
FactoryBot の README は下記。
https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#update-your-gemfile
bundle install でプロジェクトに入る
データ挿入の factries
spec/factories/bank_tranksactions.rb
これを作成
FactoryBot.define do
factory :bank_transaction do
account_number { '1234567' }
amount { 250_000 }
description { "おちんぎん" }
# sequence(:username) { |n| "user#{n}" }
end
end
呼ばれるとデータが入る factories を作る
Controller のテスト本体
spec/controllers/bank_transactions_controller_spec.rb
describe BankTransactionsController do
context 'when logged in' do
before do
FactoryBot.create(:bank_transaction)
end
it 'get all bank transactions' do
# FactoryBot.build(:bank_transaction)
# FactoryBot.create(:bank_transaction)
get :index
# pp response.body
amount = JSON.parse(response.body).first['amount'].to_i
expect(amount).to eq 250000
end
after do
BankTransaction.destroy_all
end
end
end
- describe ControllerName でコントローラー指定
- before FactoryBot.create でテスト実行前にデータを作成して DB に入れる。
- build では DB には入らない。
- get :methodName でメソッドを指定
- json が返ってくるのでパースしてキーを指定
- expect(key).to eq value で比較
- after でデータを破棄
このサイクル。
実際の実行
Terminal
エラーがある場合
rspec spec/controllers/bank_transactions_controller_spec.rb
F
Failures:
1) BankTransactionsController when logged in get all bank transactions
Failure/Error: json = JSON.parse(response.body).first.to_i
NoMethodError:
undefined method `to_i' for {"id"=>1, "account_number"=>"1234567", "amount"=>"250000.0", "description"=>"おちんぎん", "created_at"=>"2023-05-21T05:23:39.241Z", "updated_at"=>"2023-05-21T05:23:39.241Z"}:Hash
# ./spec/controllers/bank_transactions_controller_spec.rb:12:in `block (3 levels) in <main>'
ない場合
kaede0902@V bank_transactions_api % rspec spec/controllers/bank_transactions_controller_spec.rb
.
Finished in 0.08155 seconds (files took 1.77 seconds to load)
1 example, 0 failure
Posted on May 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.