Spec'ing chained calls


#1

Hello!

I’m trying to spec a method, that has several chained calls.

http://gist.github.com/78562 (spec)
http://gist.github.com/78563 (model)

In the first spec, I’m trying to focus on the method calls that have to
be
made, and the arguments they should receive.

Is there a better way to spec the behaviour for these chained calls? It
just
seems too many lines to me :slight_smile:

Thanks a lot!
Levy
PS: I’m using my branch of the twitter gem, at
http://github.com/levycarneiro/twitter, which just adds this method
‘not_retweeted’.


#2

You might want to look into using a null object, and breaking that first
spec up into several examples
(a null object returns itself when sent a message it doesn’t know how to
handle)

http://gist.github.com/78570

I’ve built more than a few named_scope chains using this pattern, and it
seems to work out okay. This approach is somewhat less brittle, in that
it’s not going to explode horribly if you change the order of the chain
in
the main method (if something else reads better, say) …

Downside is that it won’t catch if you add new methods to the chain.
If
that’s a concern, you could complicate the setup a bit, to narrow the
focus
to just the methods you want.

 @new_search = mock(Twitter::Search)
 new_search.stub!(:containing => new_search, :since => new_search,

:not_retweeted => new_search, :fetch => new_search)

On Fri, Mar 13, 2009 at 10:04 AM, Levy Carneiro Jr.


#3

Levy Carneiro Jr. wrote:

Is there a better way to spec the behaviour for these chained calls?
It just seems too many lines to me :slight_smile:

http://c2.com/cgi/wiki?LawOfDemeter

Specs are as much of a design tool as a testing tool, and the use of
mocks in your specs show just how ugly the current design is.

Either write a wrapper around the library which takes care of the method
chaining, or write integration tests against it, stubbing out some low
level detail of the library.

Scott


#4

Hello Scott,

On Fri, Mar 13, 2009 at 11:59 AM, Scott T.
removed_email_address@domain.invalidwrote:

http://c2.com/cgi/wiki?LawOfDemeter

Specs are as much of a design tool as a testing tool, and the use of mocks
in your specs show just how ugly the current design is.

Either write a wrapper around the library which takes care of the method
chaining, or write integration tests against it, stubbing out some low level
detail of the library.

Actually, the method ‘fetch_new_tweets’ is the wrapper. There’s another
method called ‘process_new_tweets’, which calls some methods from the
Tweet
class, including fetch_new_tweets.

But I see your point. Testing only the output from this wrapper
(integration
tests), and not testing the internal actions being done inside
Twitter::Search, which Tweet shouldn’t know about.

So, the ideal would be the Twitter::Search class to provide some
ready-to-use wrappers for me, the way I want it. Like the postman and
wallet
example [1]. But, since it clearly doesn’t have all wrappers I need,
shouldn’t my own class, Tweets, be doing the several wrappers and
testing
them on my own? Or, there is a better design pattern in this case?

[1]
http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

Regards,
Levy


#5

Thanks for your examples, Chris!

regards,
Levy