Jon A. Lambert wrote:
> Ben Giddings wrote:
>>
>> Ok, so in this case, what would the unit tests be?
>>
>> Ben
> 
> This one is rather tricky.
> I assume your do_something is part of a Foo class.
> I then do a hack to mock up puts to put it in a global
> 
> So your tests might look like this:
[snip tests]

My feeling is that code like we are discussing should be refactored to 
be more easily unit tested. Some developers take issue with modifying 
code for the sake of testing, but myself, XPers and others who 
extensively use unit tests tend to notice improvements in the code by 
making it test friendly. Because of the nature of unit tests, code that 
is designed to be unit tested is cohesive and has low coupling, which 
are well known metrics of software quality.

Here is my quick attempt at refactoring the "do_something()" method to 
be more easily unit tested (as well as Jon Lambert's refactored unit tests):

require 'test/unit'

# Errors should be made into Exceptions, not just printed out
class FooOverloadException < RuntimeError; end

class Foo
   # Instead of just using puts, do_something should return a String,
   # which can be further manipulated, printed out, or sent over
   # the network.
   def do_something(foo)
     s = ''
     # Using the to_i method allows for nil (which returns 0 on to_i)
     if foo.to_i > 500
       raise FooOverloadException, "Whoa, #{foo} is too many times!  I 
can't do that!"
     else
       foo.to_i.times { |i| s << "#{i}\n" }
     end
     s
   end
end

class TestFoo < Test::Unit::TestCase
   def setup
     @f = Foo.new
   end

   def test_do_something_0
     assert_equal("",@f.do_something(0))
   end

   def test_do_something_3
     assert_equal("0\n1\n2\n",@f.do_something(3))
   end

   def test_do_something_501
     exception = assert_raise(FooOverloadException) do
       @f.do_something(501)
     end
     assert_equal("Whoa, 501 is too many times!  I can't do 
that!",exception.message)
   end

   def test_do_something_nil
     assert_equal("",@f.do_something(nil))
   end
end

Now doesn't that look better? :)

Ryan