【RSpec】モデルスペック【Rails】
今日はRSpecとFactoryBotを使ったテストの書き方をまとめます。
はじめてテストを作るので基本から復習します。
テストデータを作る
今回はFactoryBotを使ってテストデータを作ります。
今まではseed.rbでサンプル用のデータを作っていましたが、FactoryBotを使えばテスト用のテストデータを作ることができます。
spec/factories/tasks.rb
FactoryBot.define do factory :task do sequence(:title, "title_1") content { "content" } status { :todo } deadline { 1.week.from_now } association :user end end
カラム名 { カラムの内容 } という書き方になっていますね。
sequence
sequenceを使うと.nextメソッドが呼び出されて、数字を増やしていくことができます。
書き方は2種類あって、
sequence(:title){|n| "title_#{n}"}
と
sequence(:title, "title_1")
のように書くことができます。
.nextの挙動はこんな感じ。
> "title_1".next => "title_2" > "title_2".next => "title_3"
association
モデルがassociationされている時に使えるメソッド。
通常、task.createとuser.createの二つを書く必要がありますが、association :userのように書いておけば、user.createを省略することができます!
同じようにspec/factories/users.rbにもuserのテストデータを作っておきましょう。
テスト要件を書く
いきなりコードを書いていくのではなく、はじめにテストしたい内容を書きます。
RSpec.describe Task, type: :model do describe 'validation' do it 'is valid with all attributes' do end it 'is invalid without title' do end it 'is invalid without status' do end it 'is invalid with a duplicate title' do end it 'is valid with another title' do end end end
☆ポイント☆ 以下の2つに分けてテストを書きます。 ・問題が起きない場合のテスト ・問題が起きる場合のテスト
describeとit
・describeメソッド RSpec.describe 'テストの対象' do
テストをグループ化して、「何についてのテストなのか」を記述する。ここでは、taskモデルについてテストすることを宣言しています。
・itメソッド It "〜" do テストをexampleという単位にまとめてくれています。 It "should be〜"やIt "is 〜"のように書き、It do ... endの中に、エクスペクテーション(期待値と実際の値の比較)を書きます。
exampleの書き方
では、実際にItの中に何を書いていくかを見ていきます。
It is valid with all attributes
「すべてのカラムがある場合に、有効である」というテストをします。
It is valid with all attributes task = FactoryBot.build(:task) expect(task).to be_valid expect(task.errors).to be_empty end
・task = FactoryBot.build(:task)
taskオブジェクトを作ります。
・expect()には検証したいものを書きます。
expect.to の場合は「〜であること」を期待するときに、expect.not_toの場合は「〜でないこと」を期待するときに使います。
・be_validはマッチャと呼ばれるものです。意味はその名の通り「有効である」という意味です。その逆で、be_invalidという「無効である」というマッチャもあります。 ちなみに、マッチャとは「期待値と実際の値を比較して、一致した(もしくは一致しなかった)という結果を返すオブジェクト」のことです。
・be_emptyというマッチャはその名の通り、「空である」という意味のマッチャです。
・(復習)errors[:attribute]はエラーがあったらエラーの配列を返すメソッド。エラーがない場合は空の配列を返します。
It is invalid without title
「タイトルがない場合に無効」という内容でテストします。
it 'is invalid without title' do task_without_title = build(:task, title: "") expect(task_without_title).to be_invalid expect(task_without_title.errors[:title]).to eq ["can't be blank"] end
オブジェクトを変数に代入するときは、役割がわかる名前にしておくと◎
・eqは「等しい」という意味のマッチャです。
FactoryBotの設定
設定に以下を記述しておくと、FactoryBot.createのFactoryBot部分を省略できるようになります。
spec/rails_helper.rb
config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") config.include FactoryBot::Syntax::Methods end
こんな感じでtask = build(:task)書けるようになっていい感じですね。
とりあえず、今回はここまでとします! おやすみなさい🐧🌙