N.B. - I'm using PHP 4.
Am I right in thinking that, in broad terms, tests should not need to access private properties of tested objects, or run private methods? I would say that this can lead to a dependency by the tests on the internal logic of the tested object, which is bad.
I ask because I've done it a lot in my first test-driven project - my test cases often start by testing smaller private methods first before the big public methods which utilises them. Of course, I could strip out the earlier tests and just test the public method, but there are some boundary conditions I find it hard to replicate if I'm only allowed to interface with public methods.
Thoughts, or links to previous discussions (I have searched but found very little), would be much appreciated. I can imagine this question has cropped up before.
Thanks!
Can a test access private methods and properties?
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
TDD involves peeking "under the hood", so even though it may not seem right to test private/protected methods, it's all part of the process. Unit testing in general, however, only stipulates testing of the public interface. It's a choice of philosophy, really: PHP 4, having no encapsulation support, will not complain either way.
Thanks. So I shouldn't worry too much, but perhaps I should strive to test public methods only in the future as a 'best practice'.Ambush Commander wrote:TDD involves peeking "under the hood", so even though it may not seem right to test private/protected methods, it's all part of the process. Unit testing in general, however, only stipulates testing of the public interface. It's a choice of philosophy, really: PHP 4, having no encapsulation support, will not complain either way.
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
Test only the public methods (or in PHP4, the ones meant as public
). A naming convention like adding an underscore in front of a private method/property name is very useful. There are, as Ambush Commander said, times when you really do need to test private methods. I find on specification heavy classes testing private methods make it far easier to locate where a problem is since in many specification heavy classes there's hundreds of lines of code, and only a few public methods (stuff like implementing a YAML lexer and parser for example). Generally though avoid like the plague - internal private methods are never (ever) intended to be a stable API and refactoring can change them fast and often meaning your tests would need a lot of updating. I also often find that where private methods need testing, it's a refactoring sign - maybe those private methods really want to be public in an extracted class? Check if they are genuinely reusable for other code.