[rspec-users] Verifying that a block calls a method

Scott Taylor mailing_lists at railsnewbie.com
Wed Apr 18 01:02:49 EDT 2007


On Apr 17, 2007, at 10:43 PM, David Chelimsky wrote:

> On 4/17/07, Scott Taylor <mailing_lists at railsnewbie.com> wrote:
>> The only clear advise I've gotten is to
>> pass my_fun3 a stream, and let the default parameter be a STDOUT
>> stream, like so:
>>
>> def my_fun3(stream = STDOUT)
>>    [1,2,3].each { |x| stream.puts x }
>> end
>>
>>
>> Every time you use this method in production, you just leave off the
>> parameter, and it defaults to calling puts (as normal).  The stream
>> parameter is only used during testing.  This is a little disturbing,
>> because now you have to change the source to fit your tests for code
>> that will never be used in production.
>
> This is a very, very common approach in static languages - often used
> to break dependencies found in legacy (read: un-tested) code.
>
> Designing for testability is a tricky thing, for exactly the reason
> you describe. You end up designing things differently than you would
> if you didn't care about testing. The trick is finding the boundaries
> that you're comfortable with. I'm not comfortable with methods that
> are only used in tests. Parameterized methods or constructors don't
> bug me at all. They serve the tests, and impose low risk of misuse.
> That risk is lowered, in my opinion, if you use a constructor
> parameterize the constructor rather than the method.
>
> class MyClass
>   def initialize(io=STDOUT)
>     @io = io
>   end
>   def my_fun3
>     [1,2,3].each { |x| @io.puts x }
>   end
> end
>
> Hope that helps.

Well it seems to be good advise.  Unfortunately, it doesn't help me  
with the Kernel#trap problem, though, which is what the email was  
originally about.

Scott



>
> David
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list