2011-06-22 15 views
0

私は本当にrspecを学ぼうと苦労しています:(そう、私はコントローラの本当に簡単な作成アクションについて私に少し助けてくれることを願っています。私はRspec :: mocksを使いたいですこれ、私はそれを行う方法である代わりにテストするときにデータベースをヒットすることを考えるとシンプルなrspecの質問

私はbefore_filterを抱えている:?。

def find_project 
    @project= Project.find_by_id(params[:project_id]) 
end 

アクションを作成し、次のようになります

def create 
    @batch = Batch.new(params[:batch]) 
    @batch.project = @project 

    if params[:tasks] 
    params[:tasks][:task_ids].each do |task_id| 
     @batch.tasks << Task.find(task_id) 
    end 
    end 

    if @batch.save 
    flash[:notice] = "Batch created successfully" 
    redirect_to project_batch_url(@project, @batch) 
    else 
    render :new 
    end 
end 

私はrですそれはどういう意味ですか?@batch.project = @projectどうすれば@projectを定義できますか?そしてまた、全体params[:tasks][:task_ids].each一部...雅は...ほとんど全部:(この初心者の質問のための

申し訳ありませんが - 正しい方向に私を指す君たちが助けるか、少なくともすることができます願っています:)

おかげ

+0

ジェスパー:ここ

は、ビューの「mockist」の点から、(未テスト)いくつかの可能なスペックです私はあなたの質問を理解することが少し難しいと思います。あなたは正確に何が難しいですか?あなたはおそらく明確化を加えるために言い換えることができますか? – iwasrobbed

答えて

0

コントローラー仕様の考え方は、アクションがインスタンス変数を設定しているかどうか、必要に応じてリダイレクト/レンダリングを行うかどうかを確認することです。仕様を設定するには、通常、オブジェクトまたはモックを作成し、属性/スタブを設定してから、必要に応じてparamsハッシュを渡してアクションを呼び出します。

ので例(空気コード)のために:

describe MyController do 
    before(:each) do 
    @project = mock_model(Project) 
    Project.stub(:find_by_id) {@project} 
    @batch = mock_model(Batch) 
    Batch.stub(:new) {@batch} 
    end 

    it "should redirect to project_batch_url on success" do 
    @batch.stub(:save) {true) 
    post :create, :batch => { :some_key => :some_value }, :tasks => { :task_ids => [1,2,3] } 
    response.should redirect_to(project_batch_url(@project,@batch)) 
    end 

    it "should render :new on failure" do 
    @batch.stub(:save) {false) 
    post :create, :batch => { :some_key => :some_value }, :tasks => { :task_ids => [1,2,3] } 
    response.should render_template("new") 
    end 
end 

あなたはたくさんにRSpec Rails docsでこれについての詳細な情報を見つけることができます。

0

BDDを使用すると、インターフェイスを定義するのに役立ちます。だからあなたのコントローラがバッチを作成し、いくつかのタスクIDを追加したいのであれば、 "あなたが望むコードを書いてください"。コントローラの実際には、コントローラからモデルにロジックをプッシュしようとすることを意味します。テストモデルはより直観的になる傾向があり、コントローラをテストするよりもはるかに高速です。

# controller spec 
describe BatchesController do 
    def mock_project(stubs={}) 
    @mock_project ||= mock_model(Project, stubs) 
    end 

    def mock_batch(stubs={}) 
    @mock_batch ||= mock_model(Batch, stubs) 
    end 

    context "POST create" 
    it "calls #create_batch_and_add_tasks on the project" 
     mock_project.should_receive(:create_batch_and_add_tasks).with(
     :batch => { :name => 'FooBatch' }, 
     :task_ids => [1,2,3,4] 
    ) 
     Project.stub(:find).and_return(mock_project) 

     post :create, :batch => { :name => 'FooBatch' }, :tasks => { :task_ids => [1,2,3,4] } 
     # consider changing your params to :batch => { :name => 'FooBatch', :task_ids => [1,2,3,4] } 
    end 

    it "redirects to the project_batch_url on success" do 
     mock_project(:create_batch_and_add_tasks => mock_batch(:save => true)) 
     Project.stub(:find) { mock_project } 
     post :create, :these_params => "don't matter because you've stubbed out the methods" 
    end 

# controller 
def create 
    @batch = @project.create_batch_and_add_tasks(
      :batch => params[:batch], 
      :task_ids => params[:tasks].try([:tasks_ids]) 
      ) 
    if @batch.save 
    ... 
+0

monocle:答えをありがとう:)と私のコントローラをスキニーを保つのを手伝ってくれてありがとう! :) コントローラのテストにrspecを使用するのは正しい方法ですか?それについてあなたの意見は何ですか? – Jesper

+0

「正しい」方法はないと思います。あなたがRSpecに慣れると、あなたは物事をどのようにテストしたいかを理解するでしょう。詳しくは、RSpecブックをご覧ください。 – monocle