以前、テストの際にTimeオブジェクトの比較があると、1秒差で落ちるという問題に対して、エントリーを書きました。
そしたら、同じようなことやっている人もいた。
と、思ったら、rubikitchさんの記事に面白いことが書いてった。
Time.nowは偽装しないとテストは書けない。
だったらこんなまわりくどいことしないでMocha使おうよ。stubで簡単に偽装できるから。
Mochaの偽装のスコープはテストメソッドが終わるまで。テストメソッドが終わったら勝手に偽装の後片付けをしてくれる。
Mocha使うとこう書ける。
def test_current_date Time.stubs(:now).returns(Time.local(1993,2,24)) assert_equal "1993/02/24", current_date end
うひゃーなんだこれー!!凄い分かりやすい。ってかかっこいい><
Mochaというgemはモックとスタブを作成するためのフレームワークらしい。ここが詳しい。
上の例では、一時的にTime.nowに疑似データを与えているというイメージでいいのだろうか。
そもそも、スタブとモックの違いがまだ分からない。
モックって言うのは、本来必要なリソースがなくてもいいように、その代わりをしてくれるものというイメージ。例えば、アプリケーションで外部の認証システムにアクセスしにいかなきゃならないと言った際に、テストでは、その代わりをしてくれる機能がモック。
def authenticate true end
で、スタブは、リソースはあるけど、リソースが持つデータをその中のあるデータに固定するというイメージだろうか。
うーん。ちょっと調べてみる。で、調べたら追記します。
追記
id:rubikitchさんよりトラバ頂いた。即効トラバに感謝です(・∀・)!!
スタブはただ偽装するだけ、モックは引数や呼ばれた回数等のチェックを行う。
チェック機能がほしいときにモックを使って、そうじゃなけりゃスタブを使う。
なるほど。rubikitchさんが実際にコードで示してくださいました。
def test_stub o = stub # foo(*args) -> 2 なる偽装をするだけ o.stubs(:foo).returns(2) assert_equal 2, o.foo(9999) end def test_mock klass = Class.new do def foo(x) bar(x*2) end def bar(x) x*3 end end o = klass.new # bar(4)が呼ばれることを期待するモック o.expects(:bar).with(4) o.foo(2) end
引数や呼ばれた回数のチェックというとこがモックのポイントか。コードレベルで見るととても分かりやすい。
rubikitchさん++