Could this controller test be made simpler?

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

Been a month since I’ve rspec, I think you can place the stubs here.

@user = mock_model(User,
login => “”,
email => “”,
password => “”,
password_confirmation => “”
)

@account = mock_model(Account,
subdomain => “”,
company_name => “”,
filename => “”
)

Good point. I guess it was the account.user, account.users.build and
all the validation methods that I thought may be unnecessary.