[rspec-users] Could this controller test be made simpler?

Chris Olsen
Mon, 28 Jan 2008 19:36:46 -0000

In a create controller method I am testing the else clause that occurs
when the model is unable to be saved.  Sounds simple enough, but because
model is created before the save and the form has to be re-filled I now
have to stub a model and all the attributes.  Since the error messages
are displayed I also have to stub some methods within the model that
allow the error messages to be displayed properly.

This small test turns into a lot of code.  So I am wondering if there is
something that I am missing to make this much simpler.  Things did start
simple, in the stubbing of the new method within the Account class and
then the save method within the @account model.  Then I get errors
reminding me to stub out the users method for the account model, then
the build method, etc

I have looked at the generated scaffold code and it is simpler, but it
seems that the relationship made between the two models is what starts
to make this more complex.

Thanks for the help.

Here is my current code:
==============  before :each do
    @account = mock_model(Account)

    #what is being tested here
    @account.stub!(:save).and_return(false)

    #User info
    @user = mock_model(User)
    users = mock("Userlist")
    @account.stub!(:users).and_return(users)
    users.stub!(:build).and_return(@user)

    #since the form is repopulated the account mock must have stub for
all the attributes
    @account.stub!(:subdomain).and_return("")
    @account.stub!(:company_name).and_return("")
    @account.stub!(:filename).and_return("")
    @user.stub!(:login).and_return("")
    @user.stub!(:email).and_return("")
    @user.stub!(:password).and_return("")
    @user.stub!(:password_confirmation).and_return("")

    #need these to satisfy the error messages
    errors = mock("errors")
    errors.stub!("empty?").and_return(false)
    errors.stub!("full_messages").and_return(["error 1",
"error 2"])
    @account.stub!(:errors).and_return(errors)
    @user.stub!(:errors).and_return(errors)

    Account.stub!(:new).and_return(@account)
  end

  it "should re-render new template" do
    post "create" #with no submitted params
    response.should render_template("accounts/new")
  end

# Controller code
  def create
    @account = Account.new(params[:account])
    @user = @account.users.build(params[:user])

    if verify_recaptcha(@account) && @account.save
      redirect_to admin_listings_url
    else
      render :action => "new"
    end
  end
--
Posted via http://www.ruby-forum.com/.