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