Timeline for What happens with methods' tests when that method become private after re-design in TDD?
Current License: CC BY-SA 3.0
14 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Oct 5, 2017 at 8:17 | comment | added | David Arno | @IMSoP, "in some languages, a method can be invisible outside its "package", but visible to other classes within that package; is that method internal and tested only implicitly". That is correct. If it's not visible outside of the package, then it's an implementation detail and so should only be tested via a public API. | |
Oct 4, 2017 at 14:26 | comment | added | IMSoP | @DavidArno Does it not just come down to your definition of "module"? In some languages, a method can be invisible outside its "package", but visible to other classes within that package; is that method internal and tested only implicitly or an API that should be tested explicitly? It depends if you view the package as composed of multiple modules (the classes). Testing certain private methods is an extension of that grey area: functionality shared by several pieces of code within a module (class), but not published by the module (class) to the next layer up (package / component / library). | |
Oct 4, 2017 at 5:03 | comment | added | gnasher729 | Before you think about making refactoring harder / easier, you should think about getting your code to work properly in the first place. That's where tests are useful. Especially tests for private methods. | |
Oct 3, 2017 at 18:15 | comment | added | candied_orange | This kind of change is hard to do strictly under the test-first red-green-refactor cycle. Fortunately there are alternative approaches that are just as reliable and formal. You can refactor the test against the red bar. The critical thing is to see the test both pass and fail. That way you're sure what is being tested. | |
Oct 3, 2017 at 18:08 | comment | added | candied_orange | The danger here is introducing untested code, even if it was formerly tested. Sure behavior might be the same but do we now have a loss of code coverage? It is possible to exercise every branch of a private method through a public method that uses it but is that happening? Be sure it is before you blithely go ahead with this refactoring. Maybe there are parts of this private method that aren't needed anymore. Maybe new tests are now called for. Public and private methods are very different. Don't ask one to suddenly switch without considering a rewrite. | |
Oct 3, 2017 at 13:05 | comment | added | Filip Milovanović | There could be valid reasons to test internals, but, if you are doing TDD, those tests are not the ones that document/describe your system, and become obsolete if the internals change. If you don't treat them that way, then they go against the very point of TDD and make refactoring difficult. | |
Oct 3, 2017 at 12:56 | comment | added | David Arno | @R.M., if I were to create an executable in a non-modular fashion, then I would be forced into choosing between brittle tests of the internals, or only using integration tests using the executable and runtime I/O. Therefore by my actual logic, rather than your strawman version, I would create it in a modular fashion (eg via a set of libraries). The public APIs of those modules can then be tested in a non-brittle fashion. | |
Oct 3, 2017 at 12:44 | comment | added | JAB | @R.M. "command line arguments" Also runtime input, etc. | |
Oct 3, 2017 at 12:37 | comment | added | R.M. | @DavidArno By that logic, if you're building an executable (rather than a library) then you should have no unit tests at all. - "Function calls are not part of the public API! Only command line arguments are! If an internal function of your program is unreachable via a command line argument, then delete it as it does nothing." -- While private functions aren't part of the public API of the class, they're part of the internal API of the class. And while you don't necessarily need to test the internal API of a class, you can, using the same logic for testing the internal API of an executable. | |
Oct 3, 2017 at 12:18 | comment | added | David Arno | "by that reasoning the internals of a module should never be tested". Those internals should never be directly tested. All tests should only test public APIs. If an internal element is unreachable via a public API, then delete it as it does nothing. | |
Oct 3, 2017 at 12:16 | comment | added | Matthieu M. | @DavidArno: I disagree, by that reasoning the internals of a module should never be tested. However, the internals of a module can be of great complexity and therefore having unit-tests for each individual internal functionality can be valuable. Unit-tests are used to check the invariants of a piece of functionality, if a private method has invariants (pre-conditions/post-conditions) then a unit-test can be valuable. | |
Oct 3, 2017 at 11:36 | vote | accept | Héctor | ||
Oct 3, 2017 at 9:55 | comment | added | David Arno | This is a good answer, save for "If your testing framework makes it easy to test private methods, and if you decide to test private methods, then you can keep them." Private methods are implementation details and should never, ever be directly tested. | |
Oct 3, 2017 at 9:25 | history | answered | Jörg W Mittag | CC BY-SA 3.0 |