Consider the following method: def name_to_terminal puts "Scott Taylor" end How would I spec this out? Scott
On 4/10/07, Scott Taylor <mailing_lists at railsnewbie.com> wrote:> > Consider the following method: > > def name_to_terminal > puts "Scott Taylor" > end > > How would I spec this out? >def name_to_terminal(io=STDOUT) io.puts "Scott Taylor" end then call it from a spec passing in a mock for io with the appropriate expectation> Scott > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 4/10/07, Scott Taylor <mailing_lists at railsnewbie.com> wrote:> > Consider the following method: > > def name_to_terminal > puts "Scott Taylor" > end > > How would I spec this out?RSpec prints to STDOUT, but the examples and implementation use an instance of IO (mocked for the examples). So you''d have something like: describe Interactor do setup { @interactor = Interactor.new(@io = mock("IO")) } it "should print name to IO" do @io.should_receive(:<<).with("Scott Taylor") @interactor.print "Scott Taylor" end end> > Scott > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 10 Apr 2007, at 13:21, aslak hellesoy wrote:> def name_to_terminal(io=STDOUT) > io.puts "Scott Taylor" > end > > then call it from a spec passing in a mock for io with the appropriate > expectationAha - this gives me an idea about the dreaded "current-time" problem def do_something(time_factory=Time) time = time_factory.new # ... end Actually I suppose it works for any class. Why didn''t I think of that before? It''s so simple!
This is a variant of the dependency injection principle. It goes hand in hand with mocking. I recommend martin fowler''s DI article for more info. On 4/10/07, Ashley Moran <work at ashleymoran.me.uk> wrote:> > On 10 Apr 2007, at 13:21, aslak hellesoy wrote: > > > def name_to_terminal(io=STDOUT) > > io.puts "Scott Taylor" > > end > > > > then call it from a spec passing in a mock for io with the appropriate > > expectation > > Aha - this gives me an idea about the dreaded "current-time" problem > > def do_something(time_factory=Time) > time = time_factory.new > # ... > end > > Actually I suppose it works for any class. Why didn''t I think of > that before? It''s so simple! > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
There is one potential pitfall w/ this approach. I still use it in
spite of the pitfall, but it''s something you should be aware of.
It''s
entirely possible to default to the wrong this:
class NotTime
class << self
def now
return ''or later''
end
end
end
class Thing do
def do_something(time_factory=NotTime)
time = time_factory.now
...
end
end
If your examples always use mocks, and never challenge the assumption
that the default is Time, you can get into trouble.
In truth, I can''t recall when this has bitten me. But it does seem
like a hole you can fall in.
On 4/10/07, aslak hellesoy <aslak.hellesoy at gmail.com>
wrote:> This is a variant of the dependency injection principle. It goes hand
> in hand with mocking. I recommend martin fowler''s DI article for
more
> info.
>
> On 4/10/07, Ashley Moran <work at ashleymoran.me.uk> wrote:
> >
> > On 10 Apr 2007, at 13:21, aslak hellesoy wrote:
> >
> > > def name_to_terminal(io=STDOUT)
> > > io.puts "Scott Taylor"
> > > end
> > >
> > > then call it from a spec passing in a mock for io with the
appropriate
> > > expectation
> >
> > Aha - this gives me an idea about the dreaded "current-time"
problem
> >
> > def do_something(time_factory=Time)
> > time = time_factory.new
> > # ...
> > end
> >
> > Actually I suppose it works for any class. Why didn''t I
think of
> > that before? It''s so simple!
> >
> > _______________________________________________
> > 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
>
On 11/04/2007, at 1:23 AM, Ashley Moran wrote:> Aha - this gives me an idea about the dreaded "current-time" problem > > def do_something(time_factory=Time) > time = time_factory.new > # ... > end > > Actually I suppose it works for any class. Why didn''t I think of > that before? It''s so simple!Usually I just have "today" or "now" as a parameter: def do_something(now=Time.now) # ... end def do_something(today=Date.today) # ... end Though there''s no reason you couldn''t mock those two method calls... -- tim