3
votes

As I continue to learn my way around TDD with RSpec 2 and Rails 3.1, I can't seem to find a solution to this problem.

I have a Users controller with a new and create action. In my UsersController spec, I have

users_controller_spec.rb

describe "POST 'create'" do
  before(:each) do
    @attr = Factory.attributes_for(:user)
  end

  it "should assign an @user variable" do
    post :create, :user => @attr
    assigns[:user].should_not be_nil
    assigns[:user].should be_kind_of(User)
  end
end

and in my UsersController,

users_controller.rb

def create
  @user = User.new(params[:user])
end

This spec is failing with

1) UsersController POST 'create' should assign an @user variable
   Failure/Error: post :create, :user => @attr
   ActionView::MissingTemplate:

I can continue to implement application code to get this test to pass, but I feel like this test should be passing as it is.

Any suggestions?

3

3 Answers

3
votes

Your create method needs to do something. Either render a template or redirect. Since you're not telling it to redirect it's assuming that you want it to render a template but when it can't find a create.html.erb file it throws an error.

You're best bet is to do either this:

def create
  @user = User.new(params[:user])
  redirect_to root_url
end

or this:

def create
  @user = User.new(params[:user])
  render :nothing => true
end
3
votes

To test rendering nothing you'll want:

expect(response).to render_template(nil)
-1
votes

I've come across this recently myself. It seems one possibility would be to rescue the error in your test.

it "should assign an @user variable" do
  begin
    post :create, :user => @attr
  rescue ActionView::MissingTemplate
    # This is okay because(/as long as) we test the render/redirect
    # in a separate spec where we don't rescue this exception.
  end
  assigns[:user].should_not be_nil
  assigns[:user].should be_kind_of(User)
end

I don't know how "correct" this solution is. On one hand, it definitely emphasizes the "testing one thing at a time" mentality, on the other, it seems kind of ugly.

Edit

I suppose you could make some nice wrappers in your spec helper, something like

def post?(action, params = {})
  post action, params
rescue ActionView::MissingTemplate
end