Testing private methods

In my unit tests, I get errors when attempting to test private or protected model methods. I’ve tried adding public :add_assertion to the class (read that somewhere) but I still get the same problem.

Anyone have any input on the best way to test these protected methods?

ed

Two things:

   1) Since they are private, they must be accessed by other methods in the class. Theefore, testing the calling methods will, by definition, provide a test of the
private methods.

   2) You could expose the private methods via a public stub in a mock object.

Tom Mornini wrote:

   2) You could expose the private methods via a public stub in a
mock object.

One of the things I love about Ruby is its access control system:
performed at runtime for maximum safety, but does not tries to be
totalitarian at all. Calling a private method is easy enough to do it when
needed but also ugly enough to prevent you overdoing it:

obj.send :my_private_method, arg_foo, arg_bar

Zsombor

What’s wrong with not testing private methods explicitly? Either the said private methods or the actions that use them should be simple enough to ‘not be tested’, aka, by testing the action, you are testing the private method. From what I’ve learned in Rails testing, whenever tests get ugly (like hijacking the class protection methods), then you’re doing something wrong. Either don’t make private/protected methods, or test those methods by testing the actions/ methods that use said private methods.

Jason

i wanted to test the protected methods specifically because they are small and easier to test. when you test a calling method (say, one that calls various protected methods), you have to verify numerous return values and conditions. It seems like there’s a lot more room for (human) error by missing a case, value, etc. Testing the methods in a more granular fashion just seemed more stabile to me.

ed

If your protected methods are small and easy to test, then they shouldn’t be complicating your public method enough to be a bother. I guess I’d like to know how complex this protected method actually is. All of my such methods are one-liners like getting a name, or doing a quick math calc and thus do not add any complexity to the test of my public method.

Jason

Calling a private method is easy enough to do it
when
needed but also ugly enough to prevent you overdoing it:

obj.send :my_private_method, arg_foo, arg_bar

You can also use a singleton method. It’s 3 more lines of code in your
test class and requires no changes in the actual code to be tested

def obj.my_private_method_publicly (*args)
  my_private_method(*args)
end

http://mathandprogramming.blogspot.com/2010/01/ruby-testing-private-methods.html

Ed Hickey wrote:

i wanted to test the protected methods specifically because they are
small
and easier to test.

Just test the public interface. If that's unwieldy, change it.

when you test a calling method (say, one that calls
various protected methods), you have to verify numerous return values
and
conditions.

No. If you really cared about the intermediate values, you'd have made
the methods public. Since you didn't, the only value worth testing is
the final return value, because that's the only one that callers have
access to.

It seems like there's a lot more room for (human) error by
missing a case, value, etc.

That's why you have tests! Write as many cases as you need.

Testing the methods in a more granular
fashion
just seemed more stabile to me.

It's actually less stable, because it's too closely dependent on hidden
implementation details. For the most part, I believe that your tests
should treat the object as a black box (to be sure, there are
exceptions).

ed

Best,