Forum: RSpec question re: stubbing out validations

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.
Barun S. (Guest)
on 2009-05-11 20:12
(Received via mailing list)
Suppose a "User" has many "widgets", and that we have a method in the
User
class that does something like:

def update_widgets
  x = ... code to do some calculations ...
  if x > 5
    new_widget = widgets.new
    new_widget.save!
  else
    widgets.first.destroy
  end

  widgets.reload
end

How would one spec this without having to worry about the validations
for
new_widget?  Is there any way in the spec to tell it to replace
instances of
save! with instances of save(false) or something along those lines?
Using
message expectations is difficult in this case because the new_widget
doesn't exist before the method is called, so there's not object that
can
ahead of time expect to receive the save! method.

Thanks..
Matt W. (Guest)
on 2009-05-11 21:57
(Received via mailing list)
On 11 May 2009, at 17:05, Barun S. wrote:

>   end
> receive the save! method.
If you have a user object in your specs, you could do this:

user.widgets.stub!(:new).and_return(mock(Widget, :save! => nil))

but you're getting into some ugly territory mixing mocks with calls to
the database (e.g. widgets.reload).

What does your spec look like?

Matt W.
http://blog.mattwynne.net
http://www.songkick.com
Barun S. (Guest)
on 2009-05-11 22:25
(Received via mailing list)
Yes, that mixture of mocking and database calls is what was giving me a
lot
of headache.  And with my actual code more than one object might be
created
in the method so stubbing out the :new method would have added a lot of
complication to my specs if I were to maintain good coverage.  I tried
using

  Widget.any_instance.stub!(:valid?).and_return(false)
but this didn't work for me (doing a google search reveals that perhaps
I'd
have to apply some sort of patch to get this functionality, which I am
not
so keen on doing).

For now I've overcome this problem by just writing my specs in such a
way
that I ensure that new_widget is a valid object.  Some of the attributes
assigned to new_widget before it is saved are dependent upon objects and
fields that I am mocking or stubbing in my specs.  I was using
oversimplified mocks, thinking I should be able to avoid dealing with
validation since that is tested elsewhere already.  But, not having
found a
way to do that I am now using more realistic mocks so that the
new_widget.save! method does not raise an error anymore.
Zach D. (Guest)
on 2009-05-12 05:15
(Received via mailing list)
On Mon, May 11, 2009 at 12:05 PM, Barun S. 
<removed_email_address@domain.invalid> wrote:
>   end
>
>   widgets.reload
> end
>
> How would one spec this without having to worry about the validations for
> new_widget?

It seems pretty important that update_widgets is able to produce
actual widgets. I would use actual models here rather than try to
stub/mock something out. After all the whole method is about creating
(or destroying) the widgets. It seems pretty central to the behaviour
of the method. However, if what you shared is the "dumbed" down
version of your code for us on the ML then perhaps there is something
complicated going on that makes it a good candidate to be designed
differently.

> Is there any way in the spec to tell it to replace instances of
> save! with instances of save(false) or something along those lines? Using
> message expectations is difficult in this case because the new_widget
> doesn't exist before the method is called, so there's not object that can
> ahead of time expect to receive the save! method.

Are you telling us the full story? In the above code you shared you
don't pass any attributes into "widget.new". So, how does it create
valid widgets in the actual app?

>
> Thanks..
>
> _______________________________________________
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users
>



--
Zach D.
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
@zachdennis (twitter)
This topic is locked and can not be replied to.