Start Specin' the News 3
Since Colin came back from RailsConf raving about BDD, I’ve found myself priming up for what previously seemed inevitable. Behavioral testing as part of a new development process. Through a better testing structure I hope to..
- better the quality of my code
- refined organization of development time
- focus on the task at hand
- providing well covered documentation
With that said… and being the HUGE social loser I am… I’ve spent the last two days writing Specs and tests using RSpec 1.0. I have to say its almost too easy writing the actual tests, whereas the process of writing some tests, writing the code and making the code pass the test has been a definite shift in the way I develop. But not an unwelcomed one! ;)
Since RSpec seems to have a real lack of helpful documentation, I find myself wondering around their API, blog posts and best guesses. I have had great success so far, until I started writing some protected/private methods.
I had initially forseen a world of testing every single line and expression of code. Until I found this tidbit of info on the rspec mailing list…
1. Should you test protected and private methods in your specs?
No. You’re specifying the behavior of an object as seen by the outside world. Of course protected and private methods aren’t available to the world, so why would you need to test them? When you’re doing state-based testing, just call a method and then verify that it returns the expected value or leaves your object in an expected state.
This was backed up by almost every post after it. Seems that as a developer testing his code, I should stick with testing the main parts of the system that, overall, accomplish my task. Verifying that they are doing what I need them to do.
Private and protected methods typically back up other parts of the system that are public. For documentation purposes, I will probably write some tests that validate the functionality of a private/protected method IF they are made public. Just keeping them commented out to satisfy my entire spec.
Quoted RSpec mailing list post and another great post after that

For example, I have a class that returns a struct based on a WMI object (basically, it's a Windows COM object). One of the WMI object members holds a date format that isn't understood by Date.parse, so I had to write a private method to handle it. It isn't part of the public interface, yet it doesn't belong anywhere else. I can't easily test it since the data is being returned as part of a larger structure.
So, I wrote a test that ensures that the private method parses the MS date format properly which is easier and better than trying to test it indirectly through the methods that call it. Furthermore, I can now copy/paste that private method where needed, secure in the knowledge that it will work properly *because I've tested it*.
BTW, you should be able to use Object#send to test private methods. It's what you have to do for Test::Unit. It's a minor pain (more or less intentionally), but nothing serious.
Dan