5 ms·
I don't know if you're quoting or referencing something, but that's fantastic.
by rob_lh 11y ago
I don't know if you're quoting or referencing something, but that's fantastic.
- SilasX 11y agoThanks! Just something I dreamed up one day when someone said "you shouldn't have unit tests for private methods because unit tests of public methods will catch them" and I extrapolated from there.
- pbh101 11y agoMy approach when I find myself wanting to test private methods is often to extract a new class, for which the methods under question form the public interface (working with Java here).
- malkia 11y agoIf you have an unit test on private members, then you can't change the implementation safely without breaking tests. The point of the unit test is to test the interface in isolation, not the implementation - e.g. do you really expect when testing a hash-map the elements to be in specific order, or do you test for their presence?
- yk 11y agoDepends. If we take the example of a library, then there are some tests which should never break ( except if the major version increases). But it is entirely sensible to check if you broke something internally during development.
- nicobn 11y agoThis is true for totally isolated unit tests but false for tests that require stubbing. You can theoretically use the same tests for a map implemented with one version of a hash table or the other. But once you start testing classes with dependencies, your tests inevitably touch implementation details. For example, unit testing a hash map that is backed by a memcached server would require some form of stubbing. The metatesting reason for this confusion is that in the example you used, the scope of unit testing is the same as the scope of integration testing. If a class has 0 dependencies, a unit test is also an integration test, because it tests all the dependencies of the class, of which there are none. So going back to your original point, your affirmation is true for full integration tests, i.e. tests that do not stub any dependency. If you do not stub your network connection to the memcached server, the same test - albeit with a different setup - can be used for a local hash table implementation.
- raverbashing 11y agoReally? > If you have an unit test on private members, then you can't change the implementation safely without breaking tests. This makes absolutely no sense You change the private implementation, you change the unit test. It's that simple Then you keep your API the same so that external users don't break. It seems to be from the same people that like to whine about "missing tests and lack of coverage" quite funnily. It seems they like to nitpick and idolize tests instead of shipping
- Lawtonfogle 11y agoThe method should still do the same thing, regardless if it is private or public. If you purposefully create a new method and get rid of the old one, regardless if this is done by creating and deleting or by modifying, then the unit test should be changed as well. In short, you are testing the interface of that private method, not the implementation.
- malkia 11y agoI've been a game developer for 15+ years (mainly C++), never used unit tests, just good old plain asserts, sometimes ad-hoc code that creates/simulates errors or slowdowns. Pretty much QA people testing your game/tools and some form of automated tests (run this level, expect this to happen). Then I changed jobs, started writing in Java (+ GoogleWebKit and Javascript), was exposed to Unit, integration and end-to-end testing. Do I know it properly? Hell no. I'm still confused. But this is what I seems to be getting out of it: You are given a black box, with inputs and outputs. There is also a spec (it could be in your head for all I know) that defines that for certain inputs, certain outpus are expected. This spec also tries to cover quite a lot distinct cases. Each such representative case of input and output is an unit test. (If your spec was really in your head, your unit tests kind of becomes it, or I like to think about it in this way - a Unit Spec :)). The tricky part is when this blackbox is internally working with other blackboxes. Unit testing is all about testing the blackbox in isolation from other blackboxes. As such one needs to isolate them away. Currently what I'm using is DI (Dependency Injection) with guice/gin/dagger to achieve that. Thanks for all comments, it seems I have to fill my gaps in what I know.
- hvidgaard 11y agoYou really shouldn't. The public methods is the interface to the surrounding code, and that is what you want to make sure works. How you implement it, with private methods or 3rd party libs is up to you. If a bug in a private method makes it past your unittests of public methods, there was an edgecase you didn't test for. It's also a matter of praticality - I simply odn't have time to write tests for each and every method.
- derefr 11y agoTo go further: define an API, write tests against that API, and then do a pass of dead-code analysis on the resulting library-plus-test-suite. Any private functions left uncalled by your public API can just be removed!
- Drakim 11y agoLet's just hope that function doesn't end up being the one that's invoked to adjust for leap years.
- lsaferite 11y agoFunny, but good point. To counter that I'd say you should have a test case to cover the leap year handling is working as expected. If you aren't testing that since it wasn't in the spec, than why would you have the code at all?
- nailer 11y agoYou have some tests to ensure your public methods don't change implementation. That isn't the purpose of all tests. A complex public API should consist of smaller private parts. When you change those smaller parts of code, you would like to know if you break something and specifically what you broke. Testing of a small, isolated chunk of code is the 'unit' in the term 'unit tests'. Unit tests on actual units of code allow you to more quickly isolate failures.
- hvidgaard 11y ago
- machinshin_ 11y agoReminded me a lot of "for want of a nail..." (Look it up)