0

I've been confused for a while about what I perceive as conflicting guidance regarding unit tests.

Prevailing wisdom advises to test private methods only using their public interface: Making a private method public to unit test it...good idea? however unit tests themselves should test the smallest units of code e.g. individual methods http://www.javaranch.com/unit-testing.jsp these methods are therefore those most likely to be suitable for unit testing, but also the most likely to be private methods in a class (at least in my experience).

To add to my difficulty, I find TDD very helpful when developing. However as I would normally start by developing the small units of code, these methods are very likely to become private, with their functionality combining to produce some public interface member - breaking all my tests.

I know that I could use reflection for this, but again, that doesn't feel like a good solution.

I'd very much appreciate some advice on this,

Many thanks

Community
  • 1
  • 1
majjam
  • 1,286
  • 2
  • 15
  • 32

1 Answers1

1

As I see it, you should always test the public methods only. The private methods are an implementation detail, so you must test them for a specific implementation (which is bad).

lets look at an example: you have a persistency class: it receives a byte array, and saves it somewhere. that class might contain a private "saveToDB" or "saveToFile" methods, but you don't really care - you just need to test the "persist" method. if the "persist" method works, it means, by extension, that the "saveToDB" or "saveToFile" worked as well.

this has another advantage. for example: "saveToDB" might not have the "isNull" check, but all the methods that call it do have it (I know it is a bad practice, but I use it for the sake of the argument) - that means that if you checked only the "saveToDB", it would have failed on null data, although it is not possible for it to happen in the real world (which means that you made an extra test + extra code that is not helpful in any way).

I will say one more thing: if you have a private method that does a very complex logic, I would suggest you to try and refactor it into multiple methods across multiple classes and then check the public methods.

I hoped it helped.

APT
  • 365
  • 2
  • 11
  • If you still have to test the private method, and you see no other way except making it public - in Java, you can use the "default" access (package protected) to still keep the code relatively safe and yet visible by the test. I would highly recommend against it, but in the real world we are sometimes forced to do ugly things... also, I think you should read the following conversation: http://programmers.stackexchange.com/questions/100959/how-do-you-unit-test-private-methods – APT Nov 20 '13 at 14:08
  • Thanks for your answer tullio. I think I'm beginning to get my head round this now. – majjam Nov 21 '13 at 09:33