2011-02-04 9 views
1

私はrspecチュートリアル(peepcodeチュートリアル)を行っています。私は足場をいくつか作り出しました。誰かが初心者のために説明を書き直す方法を説明するのを助けてくれることを願っていました。RSpec足場コントローラ、デフォルトを理解する

describe "POST create" do 

    describe "with valid params" do 
     it "assigns a newly created weather as @weather" do 
     Weather.stub(:new).with({'these' => 'params'}) { mock_weather(:save => true) } 
     post :create, :weather => {'these' => 'params'} 
     assigns(:weather).should be(mock_weather) 
     end 

end 

このコード行は、私が理解しようとしているものです私は括弧内の置かれて方法を見たことがありませんこの1

Weather.stub(:new).with({'these' => 'params'}) { mock_weather(:save => true) } 

です。これは実際にはどういう意味ですか?

{ mock_weather(:save => true) } 

答えて

1

あなたの最初の質問については「少し鮮明にする方法」、私たちはモックを使用しないことから始めました。

モックオブジェクトは、重要ではないがテストケースに存在しなければならないオブジェクトである、第2オブジェクトの予測可能な動作に依存できない場合に便利です。モックオブジェクトの典型的な使用例は、データベースクエリ、ネットワーク使用法、ファイルI/Oです。コンピュータのネットワーク接続が失われたか、データベースが使用できないため、テストが失敗しないようにします。

rails g scaffoldから得た生成コードは最適ではありません。生成されたコードは、すべてのテストを通過させる方法で生成されました。そのために、モックオブジェクトを使用します。私は彼らがなぜそれをするのかわからない、私はより良いデフォルトは、あなたが実際に何かを行う必要があるようにテストを失敗すると思うそれらを渡すには

私は生成されたモックを削除し、次のようなものだろう:私たちはモックオブジェクトを使用していない、ので、コードはいくつかのパラメータとPOSTの呼び出しを行うとことを確認するに縮小され

#spec/controllers/weather_controller_spec.rb 
describe "POST create" do 
    describe "with valid params" do 
    it "assigns a newly created weather as @weather" do 
     post :create, :weather => {'location' => 'ORD', 'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'} 
     assigns(:weather).should be_valid 
    end 

    it "should redirect you to the weather show page" do 
     post :create, :weather => {'location' => 'ORD', 'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'} 
     response.should redirect_to(weather_path(assigns[:weather])) 
    end 
    end 

    describe "without valid params" do 
    it "should notify that a location is required" do 
     post :create, :weather => {'temp'=>'35', 'sample_time'=>'2011-02-04T20:00-0500'} 
     flash[:notice].should == 'Location is required.' 
     assigns(:weather).should_not be_valid 
    end 

    it "should notify that a temperature is required" do 
     post :create, :weather => {'location' => 'ORD', 'sample_time'=>'2011-02-04T20:00-0500'} 
     flash[:notice].should == 'A temperature is required.' 
     assigns(:weather).should_not be_valid 
    end 

    it "should notify that a sample time is required" do 
     post :create, :weather => {'location' => 'ORD', 'temp'=>'35'} 
     flash[:notice].should == 'A sample time is required.' 
     assigns(:weather).should_not be_valid 
    end 
    end 
end 

お知らせオブジェクトは有効です。モデルファイルにバリデーションルールを記述しなければならないので、モックオブジェクトを使用していないので、実際のバリデーションが行われていることを確認できます。

自動生成モックファイルでは、何もする必要はありません。テストは永遠に続きます。それは悪い考え、悪い習慣です。

また、パラメータが無効であるか不足している場合を実行するテストをさらに作成する必要があることにも注意してください。また、assigns(:weather).should_not be_validを実行することで、検証が自分の仕事をしていることを確認しています。

post :createに電話するたびにパラメータ辞書を書くことは繰り返し、壊れやすく醜いです。あなたは器具の使い方を学ぶべきです。たとえば、あなたが再利用可能な、より読みやすいコードを与えるファクトリー・ガール

#spec/factories.rb 
Factory.define :weather_valid do |f| 
    f.location "ORD" 
    f.temp "35" 
    f.sample_time "2011-02-04T20:00-0500" 
end 


#spec/controllers/weather_controller_spec.rb 
describe "POST create" do 
    describe "with valid params" do 
    it "assigns a newly created weather as @weather" do 
     post :create, :weather => Factory.build(:weather_valid).attributes 
     assigns(:weather).should be_valid 
    end 

    it "should redirect you to the weather show page" do 
     post :create, :weather => Factory.build(:weather_valid).attributes 
     response.should redirect_to(weather_path(assigns[:weather])) 
    end 
    end 
... 

と。

+0

ありがとうございます。あなたの例は、事柄を非常に明確にしています。 – alenm

5

その文の意味:クラスWeathernewメソッドはパラメータ'these'=>'params'

スタブをして、これを書くために、おそらく類似しており、明確な方法は次のようになり表現mock_weather(:save => true)

の値を返します:

Weather.stub(:new).with({'these'=>'params'}).and_return(mock_weather(:save => true))

構文{ < some code>}は、スタブが呼び出されたときに実行されるcode blockを作成します。

.and_return(){}の2つの形式の戻り値はわずかに異なります。第1のケースでは、スタブがいつ定義されるかが決定され、第2のケースでは、メッセージが受信されるときが決定される。それらは一般的に交換可能です - but sometimes not。 「それは少し明確にする方法 」についてのあなたの最初の質問については

、我々は 始めることができる:私はthis answerはモックについて誤解を招くと応答に値するされて感じる

EDIT

モックを使わないことでモック オブジェクトは、 が 第2オブジェクトの予測可能な動作に依存しない場合に便利です。オブジェクトは であり、重要ではありませんが、 テストケースに存在する必要があります。 の模範的な例は、データベース のクエリ、ネットワーク使用、ファイルI/Oです。 コンピュータがネットワーク接続を失ったため、 またはデータベースが利用できないため、テストが失敗しないようにしてください。

本当に、モックは外部リソースへの依存をなくすことができますが、それだけではありません。モックの本当の価値は、まだ存在しないコードのテストを書くことができることです。たとえば、Railsではまずビューのスペックを記述することから始めます。

describe "posts/show.html.erb" do 
    it "displays the author name" do 
    assign(:post,mock('post',:author=>"Mark Twain")) 
    render 
    rendered.should contain("written by Mark Twain") 
    end 
end 

この仕様では、データベース、コントローラ、またはモデルは必要ありません。それは、ビューが文字列をレンダリングし、レンダリングされることを検証する必要があることを主張しています.Railsビューはこれをすべて考慮しています。テンプレートファイルとインスタンス変数@postの存在は、assignステートメントで処理されます。それは@postが何であるか気にしません。それは:authorにしか反応しません。

のレールg足場から生成されたコードは最適ではありません。 生成されたコードは、すべてのテストをパスする の方法で生成され、 はモックオブジェクトを使用しています。私は なぜ彼らは、私は より良いデフォルトは、 テストを失敗するだろうと思う理由を知っていないので、あなたが実際に行う必要がある 何かそれらを渡すために何か。

足場の考え方全体は、通常の使用事例で機能するコードを生成することによって時間を節約することです。生成されたテストを実際に動作させたいのではないでしょうか?

もちろん、スキャフォールディングを使用すると、BDD/TDD「テストファースト」パラダイムの周りを終了しますが、おそらくトレードオフを受け入れているか、最初にスキャフォールドを使用しないことになります。

「なぜモックオブジェクトを使うのか」に関しては、コントローラー仕様をモデルとデータベースから切り離すことができます。だからあなたが推論を知ったらそれは "最適"です。自動で

あなたは永遠に に合格していきますすべてと のテストで何もする必要はありません モックファイルを生成しました。それは悪い考えであり、悪いことは の練習です。

これらは、あなたが対象コードを壊さない限り通過します。だから彼らはコードがもはや仕様を満たすことができないような方法で新しいコードやリファクタリングを導入していないことを確実にするために回帰テストにおいて価値があります。

、お使いのモデルファイルに を 検証ルールを記述する必要がありますし、あなたが実際 検証が起こっていることを確認することができます 、モックオブジェクトを使用していないので。

この種の結合は、実際にはRailsコントローラ仕様では望ましくありません。コントローラはできるだけモデルを知っていなければならないので、コントローラの仕様では、検証が成功する(または失敗する)ときに何が起きるかを定義する必要があり、骨格によって提供されるモックはまさに​​それを行います。モデルインスタンスが与えられたパラメータセットに対して有効かどうかをテストする必要がある場合は、モデル仕様でそれを行います。

+0

ありがとうございます。私は、他の方法の代わりにデフォルトとしてそれを使用することを望みます。コードブロックのURLはブックマークされており、大きな説明と例です。 – alenm

+0

非常に良い説明。 – maru

関連する問題