What's the best way to unit test protected & private methods in Ruby?
You can bypass encapsulation with the send method:
myobject.send(:method_name, args)
This is a 'feature' of Ruby. :)
There was internal debate during Ruby 1.9 development which considered having send
respect privacy and send!
ignore it, but in the end nothing changed in Ruby 1.9. Ignore the comments below discussing send!
and breaking things.
Here's one easy way if you use RSpec:
before(:each) do MyClass.send(:public, *MyClass.protected_instance_methods) end
Just reopen the class in your test file, and redefine the method or methods as public. You don't have to redefine the guts of the method itself, just pass the symbol into the public
call.
If you original class is defined like this:
class MyClass private def foo true endend
In you test file, just do something like this:
class MyClass public :fooend
You can pass multiple symbols to public
if you want to expose more private methods.
public :foo, :bar