Mocking Models in Controller Specs

I find myself doing this kind of thing a lot in Controller Specs:

  @vacancy = mock_model(Vacancy)
  @vacancy.stub!(:reference)
  @vacancy.stub!(:title)
  @vacancy.stub!(:created_at)
  @vacancy.stub!(:updated_at)
  @vacancy.stub!(:body)
  @vacancy.stub!(:contract)
  @vacancy.stub!(:location)
  @vacancy.stub!(:salary)
  @vacancy.stub!(:benefits)
  @vacancy.stub!(:start_date)
  @vacancy.stub!(:duration)

I have to stub each of these methods so that the form renders correctly
(as I am using integrate_views). This just feels way too much code and
effort to do this. I have a spec for one controller (which just does
plain old CRUD) that is over 300 LOC – this seems a bit nuts to me when
the controller is only 50 LOC.

Does anybody have any suggestions on how to avoid this or perhaps I am
doing something wrong!?

I make use of a Factory pattern to create instances for my model unit
tests – could I use a similar pattern for a ‘mock factory’? Is anybody
doing anything similar?

~ Mark

On May 26, 2008, at 2:52 PM, Mark D. wrote:

 @vacancy.stub!(:salary)

when
the controller is only 50 LOC.

Does anybody have any suggestions on how to avoid this or perhaps I am
doing something wrong!?

Use stub_model instead (if you’re using source from github - if not
the 1.4 release is coming soon).

On May 26, 2008, at 3:52 PM, Mark D. wrote:

 @vacancy.stub!(:salary)

when
the controller is only 50 LOC.

Does anybody have any suggestions on how to avoid this or perhaps I am
doing something wrong!?

I would highly suggest using :null_object => true in view specs (or
controller specs with integrate_views):

mock_model(MyARModel, :null_object => true, :to_s => “foobar”)

stubbing :to_s is also important in view specs. If you don’t stub
to_s, to_s will be called on the mock object, and you’ll get invalid
XHTML (see this ticket:
Lighthouse - Beautifully Simple Issue Tracking)

Scott

On 26-mei-2008, at 21:52, Mark D. wrote:

  @vacancy.stub!(:salary)

when
the controller is only 50 LOC.

Or, consider moving code into the model, and test it there. See
http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model

gr,
bartz

Also, any opinions on using a Factory pattern for instantiating mocks of
models? I like the idea of maintaining mocks in one place as I
frequently use them across several specs for models that have
associations. Do you think it would create dependency issues between the
specs using that Factory?

~ Mark

Many thanks for your replies.

David C. wrote:

Use stub_model instead (if you’re using source from github - if not
the 1.4 release is coming soon).

Thanks - that helps a great deal.

Scott T. wrote:

I would highly suggest using :null_object => true in view specs (or
controller specs with integrate_views):

Thanks, that’s interesting, I didn’t know about that option… Are there
any advantages of using this approach over #stub_model?

Bart Z. (bartz) wrote:

Or, consider moving code into the model, and test it there. See
Buckblog: Skinny Controller, Fat Model

I agree, but in this case the controller really only does CRUD, and it
couldn’t really be any skinnier or it might die! Also, I don’t think
that it is the main source of the problem here, rather the fact that I
am using integrate_views which means I have to have a reasonably full
mock of any models wherever I have a form for that model.

~ Mark

All the mentioned solutions are great, but for me they implied a bit
too much hassle to set up and also, given a larger number of specs, a
bit slow.

This discussion actually motivated me to publish my own stubbing
solution that I’ve recently implemented on GitHub. (This actually is a
kind of a factory plus a dsl to define your stubs).

Like said in the readme, the code is pretty new and bugs/problems
might well be present. Please let me know if you find any.

On 27.05.2008, at 11:37, Jarkko L. wrote:

http://jlaine.net
http://dotherightthing.com
http://www.railsecommerce.com
http://odesign.fi


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

On 27.5.2008, at 10.52, Mark D. wrote:

Also, any opinions on using a Factory pattern for instantiating
mocks of
models? I like the idea of maintaining mocks in one place as I
frequently use them across several specs for models that have
associations. Do you think it would create dependency issues between
the
specs using that Factory?

I have built my own “factory” by creating methods such as mock_user in
the spec helper. That method will then fill in some reasonable values
and stub all the needed methods. Granted, the need for that is less
now with stub_model, but sometimes you also want to stub some
associations. That has certainly reduced the amount of repetition in
my specs.

//jarkko

~ Mark

Posted via http://www.ruby-forum.com/.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


Jarkko L.

http://www.railsecommerce.com
http://odesign.fi