Mochaが楽しそう

以前、テストの際に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さん++