[rspec-users] Rspecing an enumerator from outside-in woes

Matt Wynne matt at mattwynne.net
Mon Mar 2 18:44:28 EST 2009


On 2 Mar 2009, at 23:32, Shot (Piotr Szotkowski) wrote:

> Once again – thanks a ton for your response! I wish ‘The RSpec Book’
> answered my use cases; I bought it hoping I’ll learn all this stuff  
> from
> it, but it seems the most interesting chapters are not written yet. :)
>
> Matt Wynne:
>
>> Assuming you wanted to keep your focus on the Decomposer class, but
>> you knew that the concept of a Decomposition was a firm one in your
>> design, you could define an empty Decomposition class, then stub the
>> constructor to return a test double of some sort:
>
>>    class Decomposition
>>    end
>
>>    ...
>
>>    Decomposition.stub!(:new).and_return mock('Decomposition', :foo  
>> => 'bar')
>
> Ah, a very good point. :) The idea of subclassing something to make
> it testable is also interesting; I’d rather try hard to come up
> with a better spec and/or design, but it’s good to remember there’s
> a solution to keep all the code added solely for testability in one
> place.

The idea comes from this book:
http://www.amazon.co.uk/xUnit-Test-Patterns-Refactoring-Signature

There are lots of other good ideas in that book. Some of them are only  
necessary because of the awkward things statically-typed languages  
force you to do, but many of them are equally applicable to and useful  
in Ruby.

>> Ideally though, you really want to avoid testing state and instead
>> think about testing the interactions between objects. If the
>> relationship between the Decomposer and the Decomposition is for
>> one to create instances of the other, then I would be quite satisfied
>> writing mock expectations on the Decomposition's constructor, like
>> this:
>
>>     Decomposition.should_receive(:new).with [1,2]
>
> And this is exactly where you hit the nail on the head. :) I think
> my main problem at this stage of ‘getting RSpec’ is the (shrinking,
> but still existing) inability to blur the border between the RSpec  
> world
> and the world of the code under test. I happily started to use mocks  
> and
> stubs, but I keep forgetting that they can be applied to the stuff  
> from
> the ‘other’ world; I hope I’ll keep that in mind from now on.
>
> FWIW, your example on replacing
> ….should_receive(:each).and_yield(…).and_yield(…).…
> with a fake generator struck a very nice chord with
> me, and I managed to side-step the problem that all
> three of my generator types expect a varying number
> of params to their #each calls:
> http://github.com/Chastell/art-decomp/commit/9979e3b687a33fd75e6394b6297e2200b052b354

Glad it helped :)

Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com



More information about the rspec-users mailing list