What's the best way to unit test protected & private methods in Ruby?

Brent Chapman picture Brent Chapman · Nov 6, 2008 · Viewed 36.8k times · Source

What's the best way to unit test protected and private methods in Ruby, using the standard Ruby Test::Unit framework?

I'm sure somebody will pipe up and dogmatically assert that "you should only unit test public methods; if it needs unit testing, it shouldn't be a protected or private method", but I'm not really interested in debating that. I've got several methods that are protected or private for good and valid reasons, these private/protected methods are moderately complex, and the public methods in the class depend upon these protected/private methods functioning correctly, therefore I need a way to test the protected/private methods.

One more thing... I generally put all the methods for a given class in one file, and the unit tests for that class in another file. Ideally, I'd like all the magic to implement this "unit test of protected and private methods" functionality into the unit test file, not the main source file, in order to keep the main source file as simple and straightforward as possible.

Answer

James Baker picture James Baker · Nov 6, 2008

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.