Writing specs for controller methods

0 views
Skip to first unread message

Ashley Moran

unread,
Oct 19, 2008, 4:03:36 PM10/19/08
to me...@googlegroups.com
Hi,

I'm new to Merb, just starting my first app tonight. I'd like to
write a spec along these lines:

describe Items, "#new" do
before(:each) do
@item = mock(Item)
Item.stub!(:new).and_return(@item)
end
it "should display a new Item" do
<controller>.should_receive(:display).with(@item)
dispatch_to(Items, :index)
end
end

to describe this:

class Items < Application
def new
@item = Item.new
display @item
end
end

But the Merb example groups don't appear to provide access to the
controller. (Maybe it doesn't exist at this point anyway?) The
closest I can find is on the Slapp page[1], but the approach their
involves a bit too much voodoo magic for my liking (perhaps just my
opinion because I'm not yet brave enough to go poking around the Merb
spec internals).

Can anyone show me the best/a good way to write a spec for this? Any
help for a Merb n00b much appreciated.

Cheers
Ashley

[1] http://www.socialface.com/slapp/

--
http://www.patchspace.co.uk/
http://aviewfromafar.net/

Per Melin

unread,
Oct 19, 2008, 7:35:32 PM10/19/08
to me...@googlegroups.com
2008/10/19 Ashley Moran <ashley...@patchspace.co.uk>:

> Can anyone show me the best/a good way to write a spec for this? Any
> help for a Merb n00b much appreciated.

Have a look at these example specs by Yehuda:
http://gist.github.com/14910

Matt Aimonetti

unread,
Oct 19, 2008, 7:50:00 PM10/19/08
to me...@googlegroups.com
Hi Ashley,

   You might want to check on http://www.slideshare.net/wycats/testing-merb-presentation  Yehuda's presentation on testing Merb apps the Merb way.

If you generate a new 1.0RC app and then a resource you will notice that we don't generate any controller or view specs anymore. The reason being that we believe you should test the full request ad not just mock what the controller does.

Here is an example of a model, controller and request spec:

http://gist.github.com/17973

It's not complete but should help you to get started.

-Matt

Matt Aimonetti

unread,
Oct 19, 2008, 7:52:07 PM10/19/08
to me...@googlegroups.com
hmm these example specs by Yehuda where just (old) stuff we were playing with, check my specs instead, tested against 1.0 RC2

http://gist.github.com/17973

-Matt

oleg dashevskii

unread,
Oct 20, 2008, 1:33:00 AM10/20/08
to me...@googlegroups.com
Matt,

I looked at your code and noticed that you don't test what happens on an article, only responses.

E.g. in "a successful DELETE", :given => "a article exists" you check only for a redirect, but not if the article has really been deleted.
Same in "PUT" - has or hasn't article been really updated is not checked.

Was this done intentionally? If yes, why?


2008/10/20 Matt Aimonetti <mattai...@gmail.com>



--
Oleg.

Yehuda Katz

unread,
Oct 20, 2008, 1:42:37 AM10/20/08
to me...@googlegroups.com
In order to test whether the article has been deleted, go back to the list and see if it's still there. Doing this insulates your tests from refactoring, and only tests things that are visible through your interface (i.e. things you care about).

-- Yehuda
--
Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325

Jarkko Laine

unread,
Oct 20, 2008, 1:51:06 AM10/20/08
to me...@googlegroups.com

On 20.10.2008, at 2.50, Matt Aimonetti wrote:

> Hi Ashley,
>
> You might want to check on http://www.slideshare.net/wycats/testing-merb-presentation
> Yehuda's presentation on testing Merb apps the Merb way.
>
> If you generate a new 1.0RC app and then a resource you will notice
> that we don't generate any controller or view specs anymore. The
> reason being that we believe you should test the full request ad not
> just mock what the controller does.

Could you elaborate with the decision a bit, since I smell there's a
bit of a conflict with the Rspec/BDD ideas here? It seems to me that
the new way of testing in Merb is exactly the same as using story
runner/Cucumber, except that it doesn't really test the whole stack
like using stories with Webrat does.

Also, are you still encouraging unit testing for models or do you
think the full-request testing should take care of testing them as well?

//jarkko

--
Jarkko Laine
http://jlaine.net
http://dotherightthing.com
http://odesign.fi

Check out my latest book, Unobtrusive Prototype, fresh off the
Peepcode oven:
http://peepcode.com/products/unobtrusive-prototype-js

Yehuda Katz

unread,
Oct 20, 2008, 2:28:43 AM10/20/08
to me...@googlegroups.com
There's probably still a strong case for testing models, if you consider their API to be one that shouldn't change, and if changes in them is considered a "bug" in the application.

The point here is that you want to follow 3 rules of speccing:

1. Your tests should fail if you break the interface with your users
2. Your tests should not fail if the interface has not broken
3. Only write tests that confirm things that you actually care about

It doesn't necessarily violate TDD at all here. You can still test first. You just test the interface, not the internals of your application.

-- Yehuda

Julian Leviston

unread,
Oct 20, 2008, 2:46:29 AM10/20/08
to me...@googlegroups.com
One of the biggest requests from noobs I see everywhere is how to do
multiple-level items in Rails.

If we had a method of doing this that was "standard", it would be the
one of the biggest ways that I can think of to attract new users.

Make a vid, and it'll spread like viral pancakes.

Of course, all the Rails guys looking at this list would just hawk the
code and build it into Rails, but I guess that's what's so great about
Open Source, hey.

:-)

Julian.

weepy

unread,
Oct 20, 2008, 3:23:33 AM10/20/08
to merb
Sorry - what do you mean by "multiple-level items" ?

Yehuda Katz

unread,
Oct 20, 2008, 3:42:26 AM10/20/08
to me...@googlegroups.com
Yeah, If you can provide some details I'd be glad to see what we can do ;)

-- Yehuda

Michael Klishin

unread,
Oct 20, 2008, 3:50:33 AM10/20/08
to me...@googlegroups.com
2008/10/20 weepy <jona...@gmail.com>:

>
> Sorry - what do you mean by "multiple-level items" ?

I guess, forms with multiple models.
--
MK

Julian Leviston

unread,
Oct 20, 2008, 3:58:06 AM10/20/08
to me...@googlegroups.com
Hey Yehuda man :)

Here's a great example, from a project I'm working on right now:


ToobieToob has a number of teams and businesses, and each team has a number of media files. The plus buttons on the very right of each element adds more (using AJAX) and no changes persist until a set of validated records are saved in the database (ie multiple enclosed transactions).

This is one example. We have a couple of way more complex examples. (think the same, but with 8 models including sub-models being saved at the same time).

This is the primary place where Rails falls down. We have ModelName.update_all(params[:model_name].keys, params[:model_name].values) which "handles" this-style of thing, but doesn't actually provide n-tiered options where n is any value greater than 2. (ie you can have ToobieToob above, and its people/teams, but not media files, and it doesn't handle the validation for you, either).

On the one hand, this is something which should be handled by the coder, but on the other hand, having a best practice for this type of thing would save countless HOURS of most coder's lives (probably mine included, tho we have a mini-framework for this now... it's not the best, but it works).

Now, if you look above, you'll also see there is a file upload box in the media files sub-sub-section. ;-) And this works. It handles multiple file uploads and deletes vai the form (when you add a file, the plus turns into a minus).

Julian.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "merb" group.
To post to this group, send email to me...@googlegroups.com
To unsubscribe from this group, send email to merb+uns...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/merb?hl=en
-~----------~----~----~----~------~----~------~--~---


Yehuda Katz

unread,
Oct 20, 2008, 4:36:13 AM10/20/08
to me...@googlegroups.com
At one point I had an idea for a simple DSL for creating a model-like object that could be used in form_for but represented multiple models. Could you spec out how you'd expect something like that to work? I've been meaning to work on something like this for ages.

-- Yehuda

Matt Aimonetti

unread,
Oct 20, 2008, 5:06:13 AM10/20/08
to me...@googlegroups.com

Ashley Moran

unread,
Oct 20, 2008, 5:28:28 AM10/20/08
to me...@googlegroups.com

On 20 Oct 2008, at 06:51, Jarkko Laine wrote:

> Could you elaborate with the decision a bit, since I smell there's a
> bit of a conflict with the Rspec/BDD ideas here? It seems to me that
> the new way of testing in Merb is exactly the same as using story
> runner/Cucumber, except that it doesn't really test the whole stack
> like using stories with Webrat does.
>
> Also, are you still encouraging unit testing for models or do you
> think the full-request testing should take care of testing them as
> well?

In response to Per, Matt and Yehuda: I share the same concerns as Jarko.

My BDD strategy currently is this:

* Cucumber feature descriptions to drive the app the app with
Celerity. This works ONLY through the public HTTP API, meaning I will
extend that API to allow it to force a given state. (There's a simple
example of how I do all this on my blog[1].)

* RSpec behaviour examples for the controller, with all models stubbed.

* RSpec behaviour examples for individual models, avoiding DB access
where possible.

* RSpec behaviour examples for multi-model persistence where
necessary. (Less important, as the feature descriptions should cover
this behaviour unless it's unusually complex.)

I saw the generated resource specs, and have to admit I immediately
deleted them and regenerated a standard controller. (However, the
resource controller itself is a really useful example.)

My opinion of controller specs is two-sided. On one hand, that they
are too low level to allow a simple description of the app's
behaviour, because multi-action user stories involve setting state
between examples (aka making fragile assumptions). They are also
limited to describing behaviour in terms of resource requests, which
may not be enough if your GUI is complex (eg has a lot of JavaScript,
or isn't even in web browser at all.) However, this belief comes from
time spent with Rails, not Merb. On the other hand, controller specs
are too high level to cover all the possible behaviours of an app.

In my mind, the controller is just a facade than translates HTTP
requests to business logic statements, and translates business data
into HTTP responses. And that's all I want to spec really, that it
sends the right things backwards and forwards.

Another mental model is application surface area. The stereotypical
RESTful CRUD Rails app is high surface area: lots of HTTP actions, low
code complexity per action. In the degenerate case of this (an app
that runs entirely off scaffolded resources), you don't need any
controller or model specs- feature files would do. The opposite end
of the spectrum is a low surface area, high complexity app, such as
finance calculations, fleet management or accounting. These have
almost innumerable edge cases and need a thorough model-level spec
suite to fully describe their intended behaviour.

But in both cases, the controller is doing the same job, and its
complexity should be fairly (I hesitate to say entirely) independent
of the client-side functionality (again, eg JavaScript) and the model
functionality.

Phew, I think that was more of a blog post than a mailing list reply.
Rant over!

I'm interested to hear more of the merb community's opinions of BDD in
a merb app. The fact that the resource controller generator creates
valuable spec files is encouraging, even if I disagree with the
responsibility those specs should be afforded.

Cheers
Ashley


[1] aviewfromafar.net/2008/10/2/geekup-sheffield-vi-from-specification-
to-success
(look for the code link, the rest is irrelevent)

weepy

unread,
Oct 20, 2008, 5:52:05 AM10/20/08
to merb
You mean multi-model forms ?

Rails doesn't handle this very well. There are a multitude of
different ways of handling it, e.g. attribute_fu :

http://jamesgolick.com/2007/12/5/introducing-attributefu-multi-model-forms-made-easy



On 20 Oct, 07:46, Julian Leviston <jul...@leviston.net> wrote:

weepy

unread,
Oct 20, 2008, 5:53:33 AM10/20/08
to merb
and ... http://railscasts.com/episodes/75

On 20 Oct, 07:46, Julian Leviston <jul...@leviston.net> wrote:

Nik Radford

unread,
Oct 20, 2008, 5:56:12 AM10/20/08
to me...@googlegroups.com
Hey guys,

I was wondering if anyone can point me to some good tutorials / guides /
articles on using the merb-auth and merb-slices?

Google isn't being my greatest friend today.

Nik.

------------------------------------------
E-Mail: N...@Terminaldischarge.net
(We)Blog: http://blog.terminaldischarge.net

Lawrence Pit

unread,
Oct 20, 2008, 6:00:12 AM10/20/08
to me...@googlegroups.com

Ashley, your response perfectly words what I was thinking reading this
thread..

I haven't done much with merb yet, but just reading the code, I would
guess that if you include Merb::Test::ControllerHelper in your spec,
then you'd be helped with the method
merb-core:/lib/merb-core/test/helpers#dispatch_to ?

from the doc:

# Dispatches an action to the given class. This bypasses the
router and is
# suitable for unit testing of controllers.

# ==== Example
# dispatch_to(MyController, :create, :name => 'Homer' ) do
|controller|
# controller.stub!(:current_user).and_return(@user)
# end


Lawrence

Daniel N

unread,
Oct 20, 2008, 6:07:31 AM10/20/08
to me...@googlegroups.com
On Mon, Oct 20, 2008 at 8:56 PM, Nik Radford <n...@terminaldischarge.net> wrote:

Hey guys,

I was wondering if anyone can point me to some good tutorials / guides /
articles on using the merb-auth and merb-slices?

Google isn't being my greatest friend today.

Nik.


Hey Nik,

Unfortunately I haven't had a chance to write much in the way of tutorials yet on merb-auth :(  Bradly Freeley  wrote up a getting started type post at http://bradlyfeeley.com/2008/10/11/authentication-setup-with-merb-auth-and-merb-stack/

I have put up an Authenticated hello world example on the wiki http://wiki.merbivore.com/cookbook/authenticated_hello_world

Also  there is documentation in merb-auth-core that explains the different parts of merb-auth and what they do, but unfortunately not really how to use them so much.

http://github.com/wycats/merb/tree/master/merb-auth/merb-auth-core/README.textile

It's on my todo list but there's a bit of ironing to do on it before RC2.

If you have any specific questions please hit me up here or on #merb.  I'm hassox. 

Cheers


Julian Leviston

unread,
Oct 20, 2008, 6:35:46 AM10/20/08
to me...@googlegroups.com
Yeah attachment_fu is the beginning of what I've done. It'd be nice to
have that in Merb.

Julian.

Jarkko Laine

unread,
Oct 20, 2008, 7:04:38 AM10/20/08
to me...@googlegroups.com
On 20.10.2008, at 12.56, Nik Radford wrote:
> Hey guys,
>
> I was wondering if anyone can point me to some good tutorials /
> guides /
> articles on using the merb-auth and merb-slices?
>
> Google isn't being my greatest friend today.

Guys,

Could you please *start a new thread* when you have a new subject?
This is already the third topic in this same thread and it's slowly
starting to get annoying.

Both Apple Mail and Gmail will organize the mail by threads and you're
completely breaking this scheme by hijacking existing threads with new
subjects. So please send a new message to the group instead of
replying to an existing thread when you want to start a new topic.

Cheers,

Daniel N

unread,
Oct 20, 2008, 7:10:18 AM10/20/08
to me...@googlegroups.com

eh?  Yours is the third response in this thread I'm seeing in gmail.  

Jarkko Laine

unread,
Oct 20, 2008, 7:26:35 AM10/20/08
to me...@googlegroups.com
On 20.10.2008, at 14.10, Daniel N wrote:
> eh? Yours is the third response in this thread I'm seeing in gmail.

Seems that Gmail has gotten a bit wiser recently. Mail.app still shows
"Writing specs for controller methods", "Creating multi-level params
things", and "Merb-Auth and Merb-Slices tutorials" as one thread.
Regardless, the point still stands: don't respond to an existing
thread if you really are about to create a new topic.

Ashley Moran

unread,
Oct 20, 2008, 3:05:08 PM10/20/08
to me...@googlegroups.com

On Oct 20, 2008, at 11:00 am, Lawrence Pit wrote:

> Ashley, your response perfectly words what I was thinking reading this
> thread..
>
> I haven't done much with merb yet, but just reading the code, I would
> guess that if you include Merb::Test::ControllerHelper in your spec,
> then you'd be helped with the method
> merb-core:/lib/merb-core/test/helpers#dispatch_to ?
>
> from the doc:
>
> # Dispatches an action to the given class. This bypasses the
> router and is
> # suitable for unit testing of controllers.
>
> # ==== Example
> # dispatch_to(MyController, :create, :name => 'Homer' ) do
> |controller|
> # controller.stub!(:current_user).and_return(@user)
> # end

Hi Lawrence,

Thanks for the pointer there. I saw this module in the RC1 gem
source, but all the methods (apart from, for some reason, #put) were
marked deprecated. So I assumed that this was going to be removed.
But I've looked at the latest source on Github, and the deprecations
have been removed. So I guess I'm good to go with this.

Have yet to actually use it, though, so I'll let you know how I get on.

Ashley

Nik Radford

unread,
Oct 21, 2008, 12:06:51 PM10/21/08
to me...@googlegroups.com
Thanks Hassox,

I'll give those links a look this evening.

Nik

Reply all
Reply to author
Forward
0 new messages