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

aslak hellesoy aslak.hellesoy at gmail.com
Wed Apr 18 05:51:44 EDT 2007


On 4/18/07, Scott Taylor <mailing_lists at railsnewbie.com> wrote:
>
> 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.
>

If you want a concise answer, ask a short and concise question ;-) Try this:

class Mooky
  def add_sigint_handler(trapper=Kernel)
    trapper.trap("INT") { raise Interrupt }
  end
end

describe Mooky do
  it 'should install an INT trap that raises an Interrupted' do
    mooky = Mooky.new
    trapper = mock('Kernel')
    trapper.should_receive(:trap).with("INT").and_yield
    lambda do
      mooky.add_sigint_handler(trapper)
    end.should raise_error(Interrupt)
  end
end

Any other suggestions?

Aslak

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


More information about the rspec-users mailing list