mockの前にletな話
mockの使い方を調べる人柱になってたら
let使いましょうと言われたのでお勉強めも
letとは
- memoized helper method
- メモ化:呼び出しの際の結果を引数を保存し、後で同じ引数で呼び出されたら計算せずにその格納されている結果を返す
特徴
let!
- 先行評価
- 変数の値が得られた時点で評価される
- 即座に変数が初期化される
書き方
let(:変数名) { 入れたい変数 } # 例 let(:items) { items.find_by_maker_id }
{ items.find_by_maker_id }を items で呼び出すことができます
hashも入れられます
試してみた
$count = 0 let(:count) { $count += 1 } it "memoizes the value" do expect(count).to eq(1) # count = 1 expect($count += 1).to eq(2) # count = 2 end it "is not cached across examples" do # ↑ の count = 2 が呼ばれ let のとこで+1され3になる expect(count).to eq(3) end it "is not cached across examples" do expect(count).to eq(4) # 同様に4 end
it の前に毎回処理するbeforeより処理が少なくて良さそうだけど
it や let でその値に処理を加えると厄介そうな気が
テストでそんなことするもんじゃないと思うけど
追記
rspec書いてて
そこはletじゃないんだよな〜って言われたのが気になってたので聞いてみた
beforeとletの使い分け
- before
- 副作用的な処理を含むもの
- let
- 値の代入
before do @hoge = 1 @hoge += 1 # なんらかの処理 end let!(:hoge){ Item.find(1) } # 代入だけ
用意した値に処理をするならbefore、
値を代入するだけならlet
というのが最近のはやりらしいです
おまけ
インスタンス変数の遅延初期化
変数名 ||= 変数 # 例 @hoge ||= 300
インスタンス変数が定義されてない場合のみ初期化
# インスタンス変数 var が定義されていたら真を返します instance_variable_defined? # 例 unless instance_variable_defined?(:@hoge) @hoge = Fuga.find_by(fuga_id: self.id) end
参考
let and let! - Helper methods - RSpec Core - RSpec - Relish
Better Specs { rspec guidelines with ruby }
ruby on rails - When to use rspec let()? - Stack Overflow
すごいぞRSpec(letとlet!編) - ぷろぐらまねが
instance method Object#instance_variable_defined? (Ruby 2.1.0)