Testing private methods. How?

I may be wrong about some or even everything I write here. I put some of my thoughts and I count for advice and explanation.

Lately I’ve been introduced to TDD and unit testing in general. The approach of testing code is kind of a new to me (shame to admit). The lecture of Kent Beck’s TDD made me think: if I want to test my code, I have to be sure that my private methods are returning expected values as well, right?

But how to call private method in test? I’ve googled a little (or rather duckduckgoed) and stumbled upon a few solutions to that. Some are:

  1. Not testing private methods
  2. Making private methods public just to test them
  3. Not using private methods at all
  4. Making use of reflection class

Well, I don’t buy any of this (maybe except the last, but it depends on language you use).

Not testing seems ridiculous - I know private methods are rather just helpers, yet still them can be quite large blocks of code making independent calculations, thus returning values. If I’d like to test only public method which relies on let’s say 3 private methods, then I think it would be more vulnerable because of a variety of inner functions.

Making private public? Nah. It’s private for some reason, I don’t want anyone to call it.

Not using private methods? There is one answer on stack overflow suggesting that all objects methods should be public. Mostly it bases on composition of objects, yet still I’m not sure if it’s entirely possible (or I just don’t fully understand this short answer). I can agree on the importance of composing objects but to make each of them living in public? Sounds like a large set of God’s classes.

I’m not experienced with using the last solution, but I’ve already seen that depending on language reflecting class with its private methods may be complex and that seems to me not a good deal for unit tests which supposed to be fast to write and execute.

Is any of those approaches is good for testing? Or there are other ways to achieve that? I will welcome all of your thoughts and advice.

The solution really depends upon the language. I’m personally a really big fan of making split APIs, one external API and one internal API (or more depending upon your design). You then test and document each half separately. Off the top of my head, C, Julia, and Rust support this model pretty well.

Thanks for your view!

Could you explain this further?

As I understand, internal API means set of classes/methods meant to use within app creation (not meant for users usage). But is there any way other than convince to restrict that?

I am not familiar with the languages you mentioned (C just a little), I work especially with PHP and JS, yet here I seek for general rules.

It’s not ridiculous: you’re supposed to be testing that something works, not what its implementation is. The private method is in theory an invisible implementation detail. In practice that is obviously not always the case, but if large chunks of logic are occurring in private and you feel you need those tested I would say it’s likely to be strong indicator that you need to refactor those things out of that class into something that is testable.

1 Like

I’m not sure how this would work in JS or PHP, as I primarily work in compiled languages.

In C and Rust, the two languages where I know this idea the best, you define functions for external use and functions for internal use.

In C you do this by creating separate header files, one for users and one for internal use.

In Rust, you do this by setting the functions and structure members as public, public (crate), or private.

In both languages, you can still test private or internal members separately by including the private API header or running tests in the correct place. The details vary based on language.

I find it helpful to test internal utilities separately, though at a certain point those internal utility functions become so useful that they get promoted to the public API.

Yeah this approach seems sane, but they’re not OO, slightly different w/r/t TDD, particularly with what Kent Beck et al are describing – it’s an OO problem primarily. JS private class fields aren’t accessible at all, need to write accessors into the class. It’s been a long time since I used the languages but iirc same with C# and Ruby and would need to write accessors at class definition time, I can’t remember how much can be done via reflection. Java I assume is exactly the same. C++ I just assume you can wrangle it to do anything?

Yep. C/C++ it’s the wild west. You can make it do whatever crazy idea you cook up.

My biggest experience has been with hand rolled OO in C. In that case, we hide our data behind opaque pointers and then we write different APIs with different levels of access to the internal struct members.

1 Like

I remember thinking the entire concept of privacy in OO (as in specifically classical OO, Java/C#/Ruby/et al) was a bit strange because you ended up with these chunks of code where the general advice was just “don’t test it”, but I feel like I get it now. I think it’s self-policing (to an extent). If there is code that is private but that needs to be tested, then that’s an indication that either it shouldn’t be private, or that the actual code that runs that logic should be extracted, often as functions (so a class with only static methods). That would then be what gets tested. That’s not going to be part of the overall public interface of the application as a whole, and even if it is exposed, that makes no difference: they’re just bags of functions, they can’t do anything on their own. And I get there are points where this isn’t feasible, but those languages deliberately make it impossible (or at least onerously difficult) to access private class fields from outside the class

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.