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.
Nick H. (Guest)
on 2009-05-24 20: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
Fernando P. (Guest)
on 2009-05-24 20: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.
Nick H. (Guest)
on 2009-05-24 21:29
(Received via mailing list)
On Sun, May 24, 2009 at 12:49 PM, Fernando P. 
<removed_email_address@domain.invalid>
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
Rick D. (Guest)
on 2009-05-24 21:35
(Received via mailing list)
On Sun, May 24, 2009 at 12:25 PM, Nick H. <removed_email_address@domain.invalid>
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
Nick H. (Guest)
on 2009-05-24 22:00
(Received via mailing list)
On Sun, May 24, 2009 at 1:10 PM, Rick DeNatale 
<removed_email_address@domain.invalid>
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
Fernando P. (Guest)
on 2009-05-24 22: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.
Nick H. (Guest)
on 2009-05-24 22:25
(Received via mailing list)
On Sun, May 24, 2009 at 2:13 PM, Fernando P. 
<removed_email_address@domain.invalid>
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
Fernando P. (Guest)
on 2009-05-24 22: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.
Rick D. (Guest)
on 2009-05-24 23:30
(Received via mailing list)
On Sun, May 24, 2009 at 2:24 PM, Nick H. <removed_email_address@domain.invalid>
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
Nick H. (Guest)
on 2009-05-25 00: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
Nick H. (Guest)
on 2009-05-25 01:00
(Received via mailing list)
On Sun, May 24, 2009 at 3:25 PM, Rick DeNatale 
<removed_email_address@domain.invalid>
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
Mark W. (Guest)
on 2009-05-25 01:39
(Received via mailing list)
On Sun, May 24, 2009 at 9:25 AM, Nick H. <removed_email_address@domain.invalid>
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
Nick H. (Guest)
on 2009-05-28 19:13
(Received via mailing list)
On Sun, May 24, 2009 at 3:25 PM, Rick DeNatale 
<removed_email_address@domain.invalid>
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.