Forum: RSpec Class method not being stubbed

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 18:27
(Received via mailing list)
Hi guys. I'm setting an expectation on a class method. For some
reason, the method isn't being stubbed, and the expectation isn't
seeing the call.

In KeywordListsController#create, I call the private method
#create_keywords_and_associate, which calls AdSenseHeavenParser#parse
.

Thus, some of my specs set an expectation on AdSenseHeavenParser#parse
. However, that expectation isn't stubbing out #parse .

In the "output" section of my paste:
    http://pastie.org/488160
you can see that the second line is "*** create_keywords_and_associate
***". However, that string shouldn't be printed if
AdSenseHeavenParser#parse is stubbed out.

I've been beating my head against this for a couple of hours. Any
thoughts?

Thanks,
Nick
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2009-05-24 18:49
> I've been beating my head against this for a couple of hours. Any
> thoughts?
The easiest for you is to use the debugger and go through each line in
the controller.

Maybe @keyword_list.save is returning false? Stub it out and see by
yourself.
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 19:29
(Received via mailing list)
On Sun, May 24, 2009 at 12:49 PM, Fernando Perez <lists@ruby-forum.com>
wrote:
>> I've been beating my head against this for a couple of hours. Any
>> thoughts?
> The easiest for you is to use the debugger and go through each line in
> the controller.
>
> Maybe @keyword_list.save is returning false? Stub it out and see by
> yourself.

Hi Fernando. In this case, I don't think it's a matter of using the
debugger.

I've already stubbed out #save on @keyword_list, and confirmed that
AdSenseHeavenParser#parse is being called. I know the latter is
occuring because this is being displayed when the spec is run:
    *** create_keywords_and_associate ***
If AdSenseHeavenParser#parse was actually stubbed out, or wasn't
called at all, then that line wouldn't be displayed.

-Nick
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-05-24 19:35
(Received via mailing list)
On Sun, May 24, 2009 at 12:25 PM, Nick Hoffman <nick@deadorange.com>
wrote:
> Hi guys. I'm setting an expectation on a class method. For some
> reason, the method isn't being stubbed, and the expectation isn't
> seeing the call.
>
> In KeywordListsController#create, I call the private method
> #create_keywords_and_associate, which calls AdSenseHeavenParser#parse
> .
>
> Thus, some of my specs set an expectation on AdSenseHeavenParser#parse
> . However, that expectation isn't stubbing out #parse .

That's because it isn't a class method, it's an instance method, so
instead of:

AdSenseHeavenParser.should_receive(:parse).with(keyword_list_contents).and_return({:keywords
=> [], :errors => []})

You should have
controller.should_receive(:parse).with(keyword_list_contents).and_return({:keywords
=> [], :errors => []})

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 20:00
(Received via mailing list)
On Sun, May 24, 2009 at 1:10 PM, Rick DeNatale <rick.denatale@gmail.com>
wrote:
>> . However, that expectation isn't stubbing out #parse .
> --
> Rick DeNatale

Hi Rick. I'm not sure what gave you the impression that #parse is an
instance method, but it definitely isn't.

#parse is a class method inside the AdSenseHeavenParser class.
KeywordListsController doesn't have a #parse method:
    http://pastie.org/488252

-Nick
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2009-05-24 20:13
> Hi Fernando. In this case, I don't think it's a matter of using the
> debugger.

I suspect a problem in: require 'lib/adsense_heaven_parser', the code
maybe never gets out of this require statement. The debugger would allow
you to immediately clear things out.
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 20:25
(Received via mailing list)
On Sun, May 24, 2009 at 2:13 PM, Fernando Perez <lists@ruby-forum.com>
wrote:
>> Hi Fernando. In this case, I don't think it's a matter of using the
>> debugger.
>
> I suspect a problem in: require 'lib/adsense_heaven_parser', the code
> maybe never gets out of this require statement. The debugger would allow
> you to immediately clear things out.

Hi Fernando. I'm not sure what you mean by "the code never gets out of
this require statement".

However, that doesn't really matter. The call to #require shouldn't
happen, because the method is supposed to be stubbed out.

-Nick
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2009-05-24 20:35
> Hi Fernando. I'm not sure what you mean by "the code never gets out of
> this require statement".
I should have said 'the interpreter never ...'

> However, that doesn't really matter. The call to #require shouldn't
> happen, because the method is supposed to be stubbed out.
You are making a lot of suppositions that are not obvious to us. Nowhere
in your pastie is your require call stubbed.
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-05-24 21:30
(Received via mailing list)
On Sun, May 24, 2009 at 2:24 PM, Nick Hoffman <nick@deadorange.com>
wrote:
>
> However, that doesn't really matter. The call to #require shouldn't
> happen, because the method is supposed to be stubbed out.

No that's what confused me.

class KeywordListsController < ApplicationController
...
   private
...
  def create_keywords_and_associate(keyword_list_contents, keyword_list)
    puts '*** create_keywords_and_associate ***'
    require 'lib/adsense_heaven_parser'
    parsed_list = AdSenseHeavenParser.parse keyword_list_contents

The controller method has the require and then calls parse.

One thing which strikes me is that if Rails naming conventions were
being followed:

 1) the file name be lib/ad_sense_heaven_parser not
lib/adsense_heaven_parser
 2) the require wouldn't be needed since it would be autoloaded.

Perhaps the problem lies there somewhere.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 22:48
(Received via mailing list)
>> Hi Fernando. I'm not sure what you mean by "the code never gets out of
>> this require statement".
> I should have said 'the interpreter never ...'

Ah, I understand what you mean now.

>> However, that doesn't really matter. The call to #require shouldn't
>> happen, because the method is supposed to be stubbed out.
> You are making a lot of suppositions that are not obvious to us. Nowhere
> in your pastie is your require call stubbed.

I'm not sure why the call to #require would need to be stubbed.

What I'm trying to say is that I've set a message expectation on
AdSenseHeavenParser#parse , which should prevent the method from being
called in the first place.

-Nick
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-24 23:00
(Received via mailing list)
On Sun, May 24, 2009 at 3:25 PM, Rick DeNatale <rick.denatale@gmail.com>
wrote:
>    puts '*** create_keywords_and_associate ***'
>    require 'lib/adsense_heaven_parser'
>    parsed_list = AdSenseHeavenParser.parse keyword_list_contents
>
> The controller method has the require and then calls parse.

Yup! But in my specs, when the controller method calls #parse , the
stub should consume the method call.

> One thing which strikes me is that if Rails naming conventions were
> being followed:
>
>  1) the file name be lib/ad_sense_heaven_parser not lib/adsense_heaven_parser

Normally, the file would be named like that. However, the class
represents a service called "AdSense Heaven", which doesn't have a
space between "Ad" and "Sense"...or should that still cause the file
to be named "ad_sense_..."?

>  2) the require wouldn't be needed since it would be autoloaded.

I thought that everything in lib/ should be autoloaded. When I found
that lib/adsense_heaven_parser.rb wasn't being autoloaded, I figured I
was wrong, and simply #require'd it in.

> Perhaps the problem lies there somewhere.

That's a good idea. I'll look into it and let you know.

Thanks,
Nick
48641c4be1fbe167929fb16c9fd94990?d=identicon&s=25 Mark Wilden (Guest)
on 2009-05-24 23:39
(Received via mailing list)
On Sun, May 24, 2009 at 9:25 AM, Nick Hoffman <nick@deadorange.com>
wrote:

> you can see that the second line is "*** create_keywords_and_associate
> ***". However, that string shouldn't be printed if
> AdSenseHeavenParser#parse is stubbed out.
>

I don't know why the AdSenseHeavenParser call isn't being stubbed, but I
see
no reason why that string shouldn't be printed. You're not stubbing
create_keywords_and_associate.

I would remove the .with call to see if AdSenseHeavenParser is just
receiving different arguments than you expected.

BTW, class methods are generally indicated with a .; instance methods
with a
#.

///ark
49de4cd2f26705785cbef2b15a9df7aa?d=identicon&s=25 Nick Hoffman (nickh)
on 2009-05-28 17:13
(Received via mailing list)
On Sun, May 24, 2009 at 3:25 PM, Rick DeNatale <rick.denatale@gmail.com>
wrote:
> One thing which strikes me is that if Rails naming conventions were
> being followed:
>
>  1) the file name be lib/ad_sense_heaven_parser not lib/adsense_heaven_parser
>  2) the require wouldn't be needed since it would be autoloaded.
>
> Perhaps the problem lies there somewhere.

Hi Rick. I finally had some time to fix this problem, and you were
spot on. I moved
    lib/adsense_heaven_parser.rb
to
    app/models/ad_sense_heaven_parser.rb
and everything's smooth now.

Thanks for catching that!
-Nick
This topic is locked and can not be replied to.