Clear a stub

I can’t find it on the RSpec site, and my googling is turning up
nothing. Is there a way to clear a stub once set? I’m experiencing some
behavior where I have some nested describes, with “before :each” and I
need to change the stub from the parent. I thought it would just
overwrite the previous stub value, but instead it seems to turn the stub
into an array making the previous value the first element, and then the
new value the second.

Thanks,
Steve

On Sun, Jul 27, 2008 at 11:56 AM, Steve [email protected] wrote:

I can’t find it on the RSpec site, and my googling is turning up nothing. Is
there a way to clear a stub once set? I’m experiencing some behavior where I
have some nested describes, with “before :each” and I need to change the
stub from the parent. I thought it would just overwrite the previous stub
value, but instead it seems to turn the stub into an array making the
previous value the first element, and then the new value the second.

Thanks,
Steve

Can you paste your code please? Here’s an example I just whipped up
that seems to work fine…I’m using a stub defined inline, a stub
defined in two steps, and a partially stubbed object. They all shadow
the outer stub. What does your code look like?

Pat

describe “outer” do
before(:each) do
@inlined_stub = stub(“object”, :inlined_stub => :outer)
@verbose = stub(“verbose”)
@verbose.stub!(:verbose).and_return :outer
@partial = Object.new
@partial.stub!(:partial).and_return :outer
end

it “should work” do
@inlined_stub.inlined_stub.should == :outer
@verbose.verbose.should == :outer
@partial.partial.should == :outer
end

describe “inner” do
before(:each) do
@inlined_stub.stub!(:inlined_stub).and_return :inner
@verbose.stub!(:verbose).and_return :inner
@partial.stub!(:partial).and_return :inner
end

it "should work" do
  @inlined_stub.inlined_stub.should == :inner
  @verbose.verbose.should == :inner
  @partial.partial.should == :inner
end

end
end

Pat M. wrote:

Can you paste your code please? Here’s an example I just whipped up
that seems to work fine…I’m using a stub defined inline, a stub
defined in two steps, and a partially stubbed object. They all shadow
the outer stub. What does your code look like?

Pat

It looks like I was lead somewhat astray. It wasn’t the stubbing, it’s
actually something wrong with the fixture loading. The other fixtures
that load with it seem to be okay, but the ones I need are just
returning empty arrays.

describe ReservationsController, “reservations/GET” do
describe “all reservations/ GET”, :shared => true do
…snip…

 describe "with reservations" do
   fixtures :customers, :users, :products, :reservation_statuses,

:reservations, :reservation_items

   before(:each) do
     res = [reservations(:single), reservations(:cancelled),

reservations(:surprise)]
Reservation.stub!(:find).and_return(res)
end

   it "should group the reservations by date for the view assign" do
     do_request
     rd = assigns[:reservation_dates]

     rd.should have(2).items
   end
 end

end
end

Instead of ‘res’ containing an array of three reservations, it’s just an
array of three empty arrays. I know the fixtures are good because I have
used them in other specs. The ‘reservations’ collection is present, and
it is aware of appropriate keys, but it just gives back empty arrays.
Any thoughts on my new and improved problem?

I should also note that I’m running off of svn r3312 from around mid
February. At this time I cannot update to trunk, so if it’s a problem,
and it has been fixed since that time, just let me know.

Pat M. wrote:
…big snip…

Well, a lot of stuff has happened since then :slight_smile: However, I’m not sure
what your problem is still so I can’t tell you that it’s been fixed
since then. It sounds to me like you’re saying reservations(:single)
returns a Reservation object in one test, but [] in this one. Is that
accurate?

Pat

Yes, that’s exactly the case. Just empty arrays in this instance, but
appropriate Reservation objects in other places. The other thing that
gets me is that even the other fixtures at this time are correct. Like
the customers, and users are both fine. It’s just the reservations. I’ve
also tried moving the fixtures loading up higher in the describe
nesting, thinking that maybe it had something to do with being used in a
‘shared’ describe. That had no effect though. Am I tripping over some
keyword magic maybe? I have no idea what magic that might be, I’m just
thinking out loud.

On Mon, Jul 28, 2008 at 12:08 AM, Steve [email protected] wrote:

Yes, that’s exactly the case. Just empty arrays in this instance, but
appropriate Reservation objects in other places. The other thing that gets
me is that even the other fixtures at this time are correct. Like the
customers, and users are both fine. It’s just the reservations. I’ve also
tried moving the fixtures loading up higher in the describe nesting,
thinking that maybe it had something to do with being used in a ‘shared’
describe. That had no effect though. Am I tripping over some keyword magic
maybe? I have no idea what magic that might be, I’m just thinking out loud.

Not sure. Your best bet is probably to build it up piece by piece
again.

describe “with reservations” do
fixtures …

before(:each) do
puts reservations(:single)
end
end

etc. It’s super weird that it works in every other place but not
here. So I’d start from the tiniest thing possible and add lines
until you find one that breaks it.

Pat

Pat M. wrote:

etc. It’s super weird that it works in every other place but not
here. So I’d start from the tiniest thing possible and add lines
until you find one that breaks it.

Pat

So I went through and took the whole thing apart. It turns out that it
is/was a stub issue(just not quite what expected). Prior to calling the
shared describe Reservation.find was stubbed to return []. I didn’t
realize that internally the fixtures collections used find. Now that I
do, it all makes sense; since it’s just doing what I told it to.

So in a way my original question still stands. Is there a way to
“unstub” something? Because I don’t see a way around this unless I can
do that. Thanks for your help.

On Sun, Jul 27, 2008 at 3:13 PM, Steve [email protected] wrote:

actually something wrong with the fixture loading. The other fixtures that

   rd.should have(2).items
 end

end
end
end

Instead of ‘res’ containing an array of three reservations, it’s just an
array of three empty arrays. I know the fixtures are good because I have
used them in other specs. The ‘reservations’ collection is present, and it
is aware of appropriate keys, but it just gives back empty arrays. Any
thoughts on my new and improved problem?

So are you saying that
reservations(:single) == reservations(:cancelled) ==
reservations(:surprised) == []

When you print each of them out, that’s what you see?

I should also note that I’m running off of svn r3312 from around mid
February. At this time I cannot update to trunk, so if it’s a problem, and
it has been fixed since that time, just let me know.

Well, a lot of stuff has happened since then :slight_smile: However, I’m not sure
what your problem is still so I can’t tell you that it’s been fixed
since then. It sounds to me like you’re saying reservations(:single)
returns a Reservation object in one test, but [] in this one. Is that
accurate?

Pat

Scott T. wrote:

Of course there is a way - the question is, do you really want to use it?

After seeing that, no, not really. I agree with you on it likely messing
with clarity. I opted to rework my specs. It wasn’t my preferred option,
but there really wasn’t a better way. Thanks to both of you for the
help.

On Jul 29, 2008, at 12:31 AM, Steve wrote:

find. Now that I do, it all makes sense; since it’s just doing what
I told it to.

So in a way my original question still stands. Is there a way to
“unstub” something? Because I don’t see a way around this unless I
can do that. Thanks for your help.

Of course there is a way - the question is, do you really want to use
it?

Here’s how the test suite sets up stubs:

  1. you say, stub object foo with method bar, returning baz
  2. rspec aliases the original method, and then redefines it bar on foo
    to return baz
  3. your test case ends, and then rspec goes back, and re-aliases the
    method to it’s original definition.

So yes, you could call the un-stub’ed method (which I believe rspec
calls #proxied_by_rspec_#{method_name}), although I think it’ll be
ugly and confusing. But, if you really want to override the
behaviour, I’d suggest defining something like this:

class Object
def original_stub(method_name, *args, &blk)
self.send(“proxied_by_rspec_#{method_name}”, *args, &blk)
end
end

But, I think the best result is just to duplicate the stub.

Scott