Can't seem to test redirect?


#1

I’m posting to the create action and seeing the line "at the motion save
part of create in the following:

def create
@motion = Motion.new(params[:motion])
respond_to do |format|
if @motion.save
puts “at the motion save part of create”
flash[:notice] = ‘Motion was successfully created. Needs a
second’
format.html { redirect_to(@motion) }

but when I insert the line in motions_controller_spec.rb

response.should redirect_to(@motion)

I receive “got no redirect”
expected redirect to #<Spec::Mocks::Mock:0x112ec96 @name=#<Motion id:
20, title:…>>, got no redirect

Is there something missing in the test?

TIA,
Harry


#2

Harry B. removed_email_address@domain.invalid writes:

    format.html { redirect_to(@motion) }

TIA,
Harry

Can you post your example code as well? Also, are there any errors?
Here are my two guesses at this point:

  • you forgot to make a request in the example (post :create)
  • there’s some error that is keeping the action from getting to the
    redirect

Also, what is the value of response.code in the example?

Pat


#3

Pat M. wrote:

Harry B. removed_email_address@domain.invalid writes:

    format.html { redirect_to(@motion) }

TIA,
Harry

Can you post your example code as well? Also, are there any errors?
Here are my two guesses at this point:

  • you forgot to make a request in the example (post :create)
  • there’s some error that is keeping the action from getting to the
    redirect

Also, what is the value of response.code in the example?

Pat

Hi Pat,
My examples code is
before(:each) do
login_as(:username)
@motion = mock(motions(:four))
@motion.stub!(:new_record?).and_return(true)
Motion.stub!(:new).and_return(@motion)
@motion.stub!(:save).and_return(@motion)
controller.stub!(:redirect_to).with(@motion).and_return(true)

end

def do_post
post :create, {:motion => do_motion_input(“ten”)} #reads yml input
as hash
end

it “create new proposal with proposer set” do
do_post
response.should be_success
response.should render_template(“motions/create”)
response.should redirect_to(@motion)
end

The only error is the “got no redirect”
response.code is 200
HR


#4
controller.stub!(:redirect_to).with(@motion).and_return(true)

Well, I bet this is your problem. You’re stubbing redirect_to, so there
can’t possibly be a redirect!

Also, the following example doesn’t make any sense:

it “create new proposal with proposer set” do
do_post
response.should be_success
response.should render_template(“motions/create”)
response.should redirect_to(@motion)
end

Your response can be a success (HTTP 200) OR a redirect (HTTP 302), not
both.

So there are two points you need to address right now:

  • How do you want this action to behave? (success or redirect?)
  • Don’t stub behavior that you want to verify (if you want it to
    redirect, let it redirect)

Pat


#5

Pat M. wrote:

So there are two points you need to address right now:

  • How do you want this action to behave? (success or redirect?)
  • Don’t stub behavior that you want to verify (if you want it to
    redirect, let it redirect)

Pat

Hi Pat,
I am new to rspec and still trying to figure out testing the
controller. I’m not finding it straightforward for me since my app is
built and I am catching up with rspec. I had done unit and functional
testing with TestCase. But I found the individual tests awkward.

So, I constructed this example to get the create action called and a
successful response (200). That worked. The next part of the create
action on a successful @motion save is to redirect back to show the
motion.
How do I test this redirect action?

When I take out the stub for redirect I get the following error:

undefined method `spec_mocks_mocks_url’ for
#MotionsController:0x22604ec

Harry


#6

On 24 Oct 2008, at 21:57, Harry B. wrote:

Harry B. wrote:

response.should redirect_to(@motion)

What is this Motion? is it really something that you can redirect
people to? Maybe you meant redirect_to(url_for(@motion))?

private method `split’ called for #Motion:0x2259944.

My guess is that this is rails / rspec-rails trying to make a URL out
of your Motion instance. These path method errors are often rather
unhelpful.


#7

Harry B. wrote:

Pat M. wrote:

So there are two points you need to address right now:

  • How do you want this action to behave? (success or redirect?)
  • Don’t stub behavior that you want to verify (if you want it to
    redirect, let it redirect)

Pat

Hi Pat,
I am new to rspec and still trying to figure out testing the
controller. I’m not finding it straightforward for me since my app is
built and I am catching up with rspec. I had done unit and functional
testing with TestCase. But I found the individual tests awkward.

So, I constructed this example to get the create action called and a
successful response (200). That worked. The next part of the create
action on a successful @motion save is to redirect back to show the
motion.
How do I test this redirect action?

When I take out the stub for redirect I get the following error:

undefined method `spec_mocks_mocks_url’ for
#MotionsController:0x22604ec

Harry

I have the following example:

it “once motion is saved render it with show” do
@motion = mock(motions(:four))
puts “#{@motion.id}”
Motion.stub!(:new).and_return(@motion)
@motion.stub!(:save).and_return(@motion)
do_post
response.should redirect_to(@motion)

with result:

undefined method `spec_mocks_mock_url’ for
#MotionsController:0x225cba8

If I change the first line to
@motion = motions(:four)

the result is:

private method `split’ called for #Motion:0x2259944.

Harry


#8

Hi All,
I got the redirect to work with:

def do_post
post :create, {:motion => do_motion_input(“ten”)}
end

it “creates new proposal with proposer set” do
do_post
response.should be_success
end

it “once motion is saved redirects to show motion” do
@motion = motions(:ten)
@motion.stub!(:new_record?).and_return(false)
Motion.stub!(:new).and_return(@motion)
@motion.stub!(:save).and_return(@motion)
do_post
response.should redirect_to(“motions/10”)
end

Seems I had a little wrong with each combination of lines I tried.
Thanks Pat for the input about testing only one response. I stubbed out
the last response I was trying to test. In my several hours of doing
this I’m not sure whether something didn’t get saved before a test but
it isn’t clear to me what the pattern should be. I found that using
fixtures seems cleaner to me as far as getting the right input although
I’m seeing that most users are relying on mocks. I tried mocks but it
seems my tests are sensitive. Obviously I’m not yet getting it. Not
sure why more people don’t use fixtures. I used them in unit and
functional tests and didn’t have any problems there. Hopefully my
productivity with rspec will improve from here.

Thanks for your help,
Harry


#9

Matt W. wrote:

On 24 Oct 2008, at 21:57, Harry B. wrote:

Harry B. wrote:

response.should redirect_to(@motion)

What is this Motion? is it really something that you can redirect
people to? Maybe you meant redirect_to(url_for(@motion))?

private method `split’ called for #Motion:0x2259944.

My guess is that this is rails / rspec-rails trying to make a URL out
of your Motion instance. These path method errors are often rather
unhelpful.

Hi Matt,
@motion is an instance of Motion which is the item being created
here. I used a mock or a fixture and get different results. Once saved
the redirect should take me back to the show action and render the
motion object.
I tried your suggestion of url_for(@motion) and received the error:

undefined method `url_for’ for
#Spec::Rails::Example::ControllerExampleGroup::Subclass_3:0x1aed7dc

BTW - is there a way to turn off the six spec::rails::example tests?

Harry