Evan Phoenix on Testing Private Methods in Ruby
Posted by Jason Rudolph on November 2nd, 2007
At RubyConf today, Stuart Halloway’s Refactotum workshop led to a brief but excellent discussion on the various approaches for testing private methods in Ruby. Ideas ranged from the typical solution of using #send (which won’t work once Ruby 1.9 lands) to Ryan Davis’s technique of simply making everything public. Evan Phoenix, on the other hand, suggested a solution that avoids the soon-to-be-brokeness of using #send while still allowing you to benefit from the inherent intent expressed by defining a method as private.
To demonstrate, let’s assume we have the following (admittedly contrived) class:
- class Ninja
- private
- def kill(num_victims)
- "#{num_victims} victims are no longer with us."
- end
- end
So how can we make sure that the private method is doing what we want, and do so while testing it in isolation? Why not temporarily define a new public method that simply passes through to our elusive private method?
- require ‘test/unit’
- class NinjaTest < Test::Unit::TestCase
- def test_should_punish_sloppy_coders
- @ninja = Ninja.new
- def @ninja.flog_publicly(*args)
- kill(*args)
- end
- assert_equal ‘3 victims are no longer with us.’, @ninja.flog_publicly(3)
- end
- end
Sweet!
- src> ruby ninja.rb
- Loaded suite ninja
- Started
- .
- Finished in 0.000274 seconds.
- 1 tests, 1 assertions, 0 failures, 0 errors



November 16th, 2007 at 4:21 pm
Good Blog J. Rudy.
I manage to take a peek every week.
March 12th, 2008 at 1:17 pm
[…] esta dica no blog do Jason Rudolph, mas ele mesmo ouvi isto do Evan Phoenix no RubyConf no ano passado. Durante uma discussão sobre […]
April 1st, 2008 at 9:07 am
[…] esta dica no blog do Jason Rudolph, mas ele mesmo ouvi isto do Evan Phoenix no RubyConf no ano passado. Durante uma discussão sobre […]