Should I unit test private methods?
-
I used to unit test private methods, then some people advised me not to do so... What do you think? should I unit test only public methods or private methods as well?
-
I used to unit test private methods, then some people advised me not to do so... What do you think? should I unit test only public methods or private methods as well?
This is one of those questions that can end up in semi-religious wars with people wanting to burn the heretics who don't do things "their way". If you are part of a team and the standard is to just test public implementations, then you just test public implementations. If that team insists on unit testing everything, then test the private methods as well. I have to admit that I prefer tests that only test the public methods. Basically, if you have a private method that you can't get to somehow via your public methods then either that code is "dead code", or you have a serious problem with your architecture and are relying on reflection in the main codebase to get at this code and run it. Thing is, if you follow SOLID principals, no single part of your codebase should be that large that you can't adequately cover the private methods via the public methods/properties.
This space for rent
-
This is one of those questions that can end up in semi-religious wars with people wanting to burn the heretics who don't do things "their way". If you are part of a team and the standard is to just test public implementations, then you just test public implementations. If that team insists on unit testing everything, then test the private methods as well. I have to admit that I prefer tests that only test the public methods. Basically, if you have a private method that you can't get to somehow via your public methods then either that code is "dead code", or you have a serious problem with your architecture and are relying on reflection in the main codebase to get at this code and run it. Thing is, if you follow SOLID principals, no single part of your codebase should be that large that you can't adequately cover the private methods via the public methods/properties.
This space for rent
Very pragmatic! Spot on. :thumbsup:
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!
-
I used to unit test private methods, then some people advised me not to do so... What do you think? should I unit test only public methods or private methods as well?
I would say that you have to test both, sorry. Just to prevent you from hiding complexity in the private members and having each public member point to something private. Bad of trust? Yes, but also a fan of proving that stuff works as intended. Too much proof is never a negative, is it?
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
-
I would say that you have to test both, sorry. Just to prevent you from hiding complexity in the private members and having each public member point to something private. Bad of trust? Yes, but also a fan of proving that stuff works as intended. Too much proof is never a negative, is it?
Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]
Yes, I agree with you. I think that there's no such thing as too many unit tests!
-
This is one of those questions that can end up in semi-religious wars with people wanting to burn the heretics who don't do things "their way". If you are part of a team and the standard is to just test public implementations, then you just test public implementations. If that team insists on unit testing everything, then test the private methods as well. I have to admit that I prefer tests that only test the public methods. Basically, if you have a private method that you can't get to somehow via your public methods then either that code is "dead code", or you have a serious problem with your architecture and are relying on reflection in the main codebase to get at this code and run it. Thing is, if you follow SOLID principals, no single part of your codebase should be that large that you can't adequately cover the private methods via the public methods/properties.
This space for rent
Don't you think that testing only the public methods creates a problem? When a test of a public method fails, it is not clear where it fails. Is it in the public method called directly by the test, or in a private method called by the public method?
-
Don't you think that testing only the public methods creates a problem? When a test of a public method fails, it is not clear where it fails. Is it in the public method called directly by the test, or in a private method called by the public method?
Member 13624012 wrote:
Don't you think that testing only the public methods creates a problem?
No I don't.
Member 13624012 wrote:
When a test of a public method fails, it is not clear where it fails. Is it in the public method called directly by the test, or in a private method called by the public method?
Where it occurs is immaterial; the important thing is that the test failed. You have a predictable input (or set of inputs) going into a method that cause it to fail; debugging through the failure is a simple enough task that it doesn't matter. To put things into perspective; if you have to debug private methods, you are introducing a coupling in that your test has to know how the methods behave and recreate the conditions necessary immediately before calling the method, so you need to take things like state into account. What you have done here is make it harder to change the working of code because any change will probably necessitate changing the tests as well. This is testing the "how" of the code. If you are testing public methods, you are more likely to be testing the behaviour of the code, so the inner logic has much more room to change. An example might suffice here. Suppose I have a piece of code that writes to a log and returns a value to indicate that the log was successfully updated, and I have a test to ensure I get that value back; now, if I just test the public call of WriteToLog, I can ignore what happens inside and check the return value to ensure I get the expected one back - I'm ignoring the fact that, initially, I was logging to the file system (the how) and am now logging to a database. As long as I get that value back, I know that the particular piece of code behaved itself. This becomes much more important when you consider that I build up systems organically, so my initial internals would probably be a dummy logger which I would then build out and replace.
This space for rent
-
I used to unit test private methods, then some people advised me not to do so... What do you think? should I unit test only public methods or private methods as well?
The opinions vary on this subject, so I'll say it depends. Those who oppose testing private methods, claim that you should only test the public API. This makes a certain sense, as testing private methods will usually lead to testing implementation, while unit tests should test behavior and if that code needs to be tested then there's a code smell and a design problem. Also by testing public API you indirectly already test the private method - that's also what encapsulation is for. The private testing proponents claim that you should test as much logic as possible and if there's a reason to test a private method you should. I believe that good design would usually reduce the need for testing private methods, but there are still some reasons for testing private methods. Let's not forget that there's also a lot of legacy code that wasn't designed to be testable, so testing private methods would make more sense in order to refactor that code. Problem with that is how to test private methods, as mocking is usually limited to public and virtual methods unless you use "unlimited" mocking tools. So you should decide what is the right path for you or your team, just be consistent.
-
I used to unit test private methods, then some people advised me not to do so... What do you think? should I unit test only public methods or private methods as well?
It depends on your risk-estimation. If you think the private methods are fault-free. => No UnitTest If you think the private methods can have bugs, but the consequences are tolerable. => No UnitTest If you think the private methods can have bugs, but the consequences are NOT tolerable. => Unittest them. Example 1: If you are contributing "private" code to your team and you think some bugs are tolerable => No Unittest. Example 2: If your "private" code controls the cooling-system of a nuclear power-plant and you think the risk of bugs is tolerable => No UnitTest If you consider your question in this way (as I do in practice), the answer is quite easy. If you still don't know what to do, ask your boss, if he accepts bugs in "private" code or not.