[rspec-users] lots of nil problems!

Patrick J. Collins patrick at collinatorstudios.com
Sat Mar 20 03:28:50 EDT 2010

Hi Nick,

Thank you very much for your reply.  One thing I am finding incredibly
frustrating with Rspec, is that I don't even know what questions to ask--
because I find the whole thing so confusing.  So forgive me, but I am going to
break down your code and ask specific questions to hopefully gain

1.  Ok-- so in your example (which I greatly appreciate), you have this do_action
method..  Is that where I would put something like

get :create, :format => :pdf



2. Next in the before each block, you set @address..

Now, I have factory girl installed and have used it in cucumber, is that
something that could be used instead of setting @address to "123 some st" ?  Is
that common practice and acceptable to do?

3.  You set shipping_setting to mock the model Setting with
:address set to @address....

>From my understanding of what I've read--  Mocking a model,
simply means that it's a fake object, that acts like the real
thing------  So, when you do that mock_model, is it virtually
the same to have just done:
@shipping_setting = Setting.create(:address => @address)

?  That would be utilizing the test database, correct?  By
using mock_model, nothing is being stored, right?  It's more
just temporary data in memory... ?

4.  You do .stub! ...........  This is where I get really
confused.  From the peepcode screencast that I have watched
several times, he explained that stubbing is the same as
mocking-- except there is no expectation of what it returns.

That made sense when he said it, but in all the examples I've
seen with code (including yours), there is this .and_return at
the end..  Which as far as I can tell, is an expectation..  I
mean, you are asking it to return a specific thing-- that is
an expectation is it not?  Or does expectation really mean
something else in this context?

That aside, if I try to guess what this Setting.stub! this is
doing-- it is pretending that you are actually looking for a
record, and getting it.....  but in this case, is that even
worth doing?  I mean, the shipping_setting record is really
only important in the sense that the record is needed to
provide a valid "from" address for a label..  But, if we're
dealing with a test database where a from address doesn't
exist-- then it seems kind of pointless..  To clarify, the
importance for me would be to have a test that actually looks
in my real database and makes sure there is a shipping from
address in there...  I have no idea if this paragraph will
make sense to you, but hopefully it will.

5.  the it "finds the shipping address setting" block--
totally confused by this, since it's doing the same thing as
in the before :each block-- except it's mocking instead of
stubbing..... agh.. totally confused.. don't get it.. don't
even know what question to ask in hopes to get it.

6.  same with the "gets the address from the setting" block...

........  I am sorry for being so confused!!!!  If you can
break this down, I'd really appreciate it.

Thank you.

Patrick J. Collins

On Sat, 20 Mar 2010, Nick Hoffman wrote:

> Hey Patrick.
> > I have this in my controller action:
> > 
> > from_address = Setting.find_by_name("shipping_from_address").address
> > 
> > and my spec fails:
> > 
> > NoMethodError in 'Admin::ShippingLabelsController should render a pdf
> > file'
> > undefined method `address' for nil:NilClass
> > 
> > yet in the console I can do:
> > 
> >>>  Setting.find_by_name("shipping_from_address").address
> > 
> > => #<Address id: 1970, label: .... etc>
> > 
> > and I get the address-- so I don't understand why it's failing in the
> > spec.. ?
> Your console was most likely running in the development environment, and 
> thus using your development database. Specs run in the test environment, 
> and use your test database. Thus, your specs won't see the data in your 
> dev DB.
> Also, your test DB is wiped clean at the beginning of all of your tests. 
> That way, existing data can't taint or skew the results of your specs.
> You probably want something along the lines of this:
> http://pastie.org/878189
> However, that line of code of yours should be modified slightly. At the 
> moment, it'll raise the error that you posted above if the setting isn't 
> found. This is because Setting.find_by_name returns nil if the setting 
> isn't found, and nil#address doesn't exist.
> You can put Object#try right before the call to #address, like this:
>   Setting.find_by_name('...').try(:address)
> I'd probably break the line into a few: search for the setting, then 
> check if it's nil, then grab the address or deal with the nil value.
> There're many solutions. Try a few and see what feels right to you.
> -- 
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list