File.foreachのスタブ
先日 モックとスタブ - 日々此妄想 の悩み
File.foreachみたいなブロック付きメソッドのスタブってどうやって書くのかなぁ。。。。
Young risk taker.: [RSpec] Mock API を見ていて、たぶん and_yield だというところまでは目をつけていた。
yield
わかってるつもりだったけど、ちょっと甘かったっぽい。
def foo yield(1,2) end foo {|a,b| p [a, b] } # => [1, 2] (要するに p [1, 2] を実行した)
これは理解できてたんですよ。はい。
じゃー Array#each みたいなのはどうするのか理解できてなかったっぽい。*1
で、and_yieldを知るには、まずyieldだと思ってRubyのリファレンスを見ました。すると目から
def bar yield 10 yield 20 yield 30 end # barに「1引数手続き、その働きは引数に3を足してpで印字する」というものを渡して実行させる bar {|v| p v + 3 } # 13 # 23 # 33 (同じブロックが3つのyieldで3回起動された。 # 具体的には p 10 + 3; p 20 + 3; p 30 + 3 を実行した)
鱗!!!!!!!!
へー、そうなんだ。そうだったんだ。しらなんだ。yieldってそうやって使うのね(恥)
と、いう事で and_yield
さて、では File.foreach のスタブはどう書くか。。。
こうしてみた。
File.stub!(:foreach).and_yield('1| one') File.foreach('text_file') do |line| line.split[1] # => 'one' end
まぁ、これは悩む前もできてた、問題は複数行の時
こうしてみた。
File.stub!(:foreach).and_yield('1| one').and_yield('2| two').and_yield('3| tree') File.foreach('text_file') do |line| line.split[1] # => 'one', 'two', 'tree' end
やったー。できたー。
yieldってそうやってつかうのねー。なるほどなるほど。
という事で、もうちょっとスマートに
text_file = %w(1| one 2| two 3| tree) foreach_stub = File.stub!(:foreach) text_file.each do |line| foreach_stub.and_yield(line) end
とか、しとくんですかね?