I consider myself an intermediate-to-advanced rubyist and rails programmer. I've embraced TDD but sometimes wonder if I'm just doing it wrong. I feel like it can take me longer to get the specs done then should be necessary.
I'll give a very specific example from a project I was working on last night. I was working on a feature in a personal budget-management application to be able to deposit and withdraw funds from/to an 'account'. I wrote a request/integration spec using capybara to go through the interaction from a browser's point of view - I went through every possibility: If a user deposits funds, the new amount should be displayed for the account If a user withdraws funds: If there are enough funds remaining show the new amount If there are not enough funds only allow the amount field to become negative if the negative_overflow_id is the account itself (show the new amount) If there are not enough funds and the negative_overflow_id is another account, remove the remaining amount from that account and display the new amounts on both this account and the other account. If there are not enough funds and no negative_overflow_id is set, return an error on the field to the user indicating the problem. This part I'm ok with, I think there should always be a walkthrough of the full process that takes the entire stack into account. Since I'm somewhat thorough in my request specs, I tend to skip view tests and most of the controller tests (I'll throw in some controller tests for certain cases) because all of them together just take an inordinate amount of time to finish. I run the tests, I get red. I throw together the view and controller enough so that the tests give me this error: undefined method update_amount on Account My controller is thin, and the view is simple. One field (amount) with two submit buttons ("Withdraw" and "Deposit"). The controller does this: if @account.update_amount(params[:account][:amount], params[:commit]) All is well in the world. Now I drop down to model specs. I write all of the expected cases for the model first before even defining the method. (Is this how you're supposed to do it? My Account model spec ends up having 27 assertions (27 separate it "should" blocks, mind you - I've joined the 'don't put multiple assertions in one it block' camp) for this one method. The method appears that it is going to attempt to do too much, and I'm very aware of this as I'm writing the specs. But I want to have the 'end result' mapped out before I write up the method. My method, when all is said and done, ends up looking like this: https://gist.github.com/956156 To implement the edge cases defined above I setup some before validation and before update filters. My spec for the method passes, so I know it's doing what I want (in some fashion), but as I was writing the code to make it work I failed to write any specs for the callbacks that the model makes to implement the functionality. I'm not sure what path I *should* have taken instead. Some camps seem to think that you should stub off and use .should_receive calls for specific behavior in a tested method to keep it isolated... but then how do you really know that it's adhering to the other methods' parameters and such? Also if you do that, aren't you mocking up implementation in your spec which your test shouldn't care about at all (only the end result). Should I keep this test with it's 27 assertions, and then write another 20 or so for all of the callback methods that help to implement it's behavior? It takes so long to get the request specs and method specs written and then I end up having to re-write many of them because of how I implemented the method. Does anyone have thoughts on how this is supposed to be done in a TDD fashion? _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users