Rspecについて、前回調べきれていなかった項目について調べた。
気づいたことを順不同で調べたため取り留めないです。
実は遅延評価される let
遅延評価されるという特徴を知らずに、ハマってしまいました。
user_spec.rb
describe User do
let(:user) { User.create(name: 'piyoko', email: 'qqq@hoge.jp') }
it 'Userの取得ができる' do
expect(User.first).to eq user
end
end
-
let
は遅延評価される - expect(User.first)を呼び出した時点では、let(:user)が実行されていないのでnilになる
-
before do
で明示的に呼び出しておくか、もしくはlet!
を使うと良い
user_spec.rb
describe User do
let!(:user) { User.create(name: 'piyoko', email: 'qqq@hoge.jp') }
it 'Userの取得ができる' do
expect(User.first).to eq user
end
end
let!
すごい
subjectとは
- テストする対象のオブジェクト(orメソッドの実行結果)が決まっている場合は、subjectを使用することでまとめることができる
- subjectとis_expectedはセットで使う
-
is_expected
はsubject
のインスタンス変数を呼び出しているので、subject
に渡しておいた値が評価される
user_spec.rb
require 'spec_helper'
describe User do
let(:user) { User.new(name: "pi----yo", email: "piyo@hoge.com", use_count: 2) }
subject { user.repeat_user } <= これと
describe '#repeat_user' do
it '二回以上購入(リピートユーザー)ならtrueが返る' do
is_expected.to be true <= これがセット
end
it '一度も購入していない場合は falseが返る' do
user.use_count = 0
is_expected.to be false <= これがセット
end
end
end
Factory_bot便利そう
導入部分は割愛
- spec/factories/user.rb
にデータを準備しておく
spec/factories/user.rb
FactoryBot.define do
factory :user do
name { "piyo_user" }
end
end
factory :hogeuser, class: User do
のようにするとclass名と違う名前もつけられるらしい
createかbuildで生成する
# DBへレコード保存
@user = create(:user)
# モデルのみの作成
@user = build(:user)
使用例
user_spec.rb
require 'spec_helper'
describe User do
before do
@user = build(:user)
end
describe 'validations' do
it "name", :aggregate_failures do
@user.name = "piyopiyo"
expect(@user.valid?).to eq(true)
@user.name = ""
expect(@user.valid?).to eq(false)
end
end
end
テスト書いてくぞ。