1

rspec でコントローラーをテストしようとしていますが、常にエラーが発生します。

users_controller.rb:

def update
    @user.update_attributes!(params[:user])

    redirect_to @user, :status => 202, :text => render_to_string(:partial => "users/show", :type => "json", :locals => {:user => @user})
    #notice, that redirect_to was reinitialized and :text is a parameter for response_body
end
_show.tokamak
user {
  id user.id
  email user.email
  username user.username
}
仕様ファイル
it "should NOT update user username" do
      username = @user.username
      put 'update', :id => @user.id, :user => {:username => username+"abc"}, :format => :json
      response.status.should be(202) 
      response.headers["Location"].length.should be > 0
      puts response.body
      @user.reload
      @user.username.should eq(username)
      end
    end

だから私はエラーが発生します:

失敗/エラー: put 'update', :id => @user.id, :user => {:username => username+"abc"}, :format => :json ActionView::Template::Error: You have aあなたがそれを予期していなかったときの nil オブジェクト! Array のインスタンスを期待していたかもしれません。nil の評価中にエラーが発生しました _app_views_users__show_tokamak___509498818 _32151168_368311673' # C:/Users/makaroni4/XXX/XXX/app/controllers/users_controller.rb:22:in 。レベル) in '

render_to_string メソッドの呼び出しが間違っているのでしょうか?

4

1 に答える 1

1

find をスタブ化してみてください。

mock_user = User.stub(:find).with(@user.id) {@user}

正直なところ、私はさらに数歩進んで、User オブジェクト (または @user が何であれ) の関連する動作のほとんどをモックしてスタブするようにします。モデル自体が正しいことを行うのではなく、有効な入力を与えた場合にコントローラーのアクションが期待するものを返すことのみをテストしていることに注意してください。

モデルとコントローラーの仕様の違いに頭を悩ませました...

これがお役に立てば幸いです...そうでない場合は、事前にお詫び申し上げます...

編集:

これをさらに一歩進めて、このテストが実際にはモデル テストであることを提案します。実際のコントローラ テストは、仕様テストの動作と同じように次のようになります。

it "should NOT update user with invalid input" do
  mock_user = mock_model(User, {}).as_null_object
  User.stub(:find).with("12") {mock_user}
  User.stub(:update_attributes).with({}).and_return(false)
  put 'update', :id => "12"

  # test that your output is correct, or even if the render target is what you expect.

end
于 2011-05-17T12:18:37.467 に答える