On Thu, Feb 19, 2009 at 8:20 AM, Stephen Eley <sfe...@gmail.com> wrote: > On Thu, Feb 19, 2009 at 12:58 AM, David Chelimsky <dchelim...@gmail.com> > wrote: >> >>> Also, while I used to be very anal and write "should >>> have(1).error_on(:login)" and such, I eventually realized that there's >>> no point. Checking on 'valid?' is entire and sufficient. >> >> I think this depends on whether or not error messages are part of the >> conversation w/ the customer. If not, that seems fine. > > But "should have(1).error_on(:login)" isn't a test on error messages. > It's a test on a key called :login. The conversation with the > customer has no bearing on that; the customer's never asked about the > errors data structure.
The code in the examples are for developers. The docstrings are for customers. In this very specific case, the matcher doesn't support the specific error message, but if it did, the example would be: describe User do context "with punctuation in the login" do it "raises an error saying Login can't have punctuation" do user = User.generate(:login => "my.login!name") model.should have(1).error_on(:login).with("can't have punctuation") end end end Even without that ability, this would be fairly expressive to both customer and developer: describe User do context "with punctuation in the login" do it "raises an error saying Login can't have punctuation" do user = User.generate(:login => "my.login!name") model.should have(1).error_on(:login) end end end > I do check for error messages making it to the user, but not in my > model specs. Those get checked in my request specs. (Or my Cucumber > features, whichever I'm doing that day.) So again, it's covered; just > not twice. This is where this all gets tricky. TDD (remember? that's where this all started) says you don't write any subject code without a failing *unit test*. This is not about the end result - it's about a process. What you're talking about here is the end result: post-code testing. If you're true to the process, then you'd have material in both places. The cost of this is something that looks like duplication, but it's not really, because at the high level we're specifying the behaviour of the system, and at the low level we're specifying the behaviour of a single object - fulfilling its role in that system. The cost of *not* doing this is different in rails than it is in home grown systems. In home grown systems, since we are in charge of defining what objects have what responsibilities, the cost of only spec'ing from 10k feet is more time tracking down bugs. In rails, this is somewhat mitigated by the conventions we've established of keeping types of behaviour (like error message generation) in commonly accepted locations. If a merb request spec or cucumber scenario fails on an error message, we can be pretty certain the source is a model object. But even that is subject to the level of complexity of the model. If a view is dealing with a complex object graph, then there are multiple potential sources for the failure, in which case there is some benefit to having things specified at the object level. >> But my validation specs do tend to be closely tied to AR methods like >> valid?(), which, as your example suggests, is impeding my ability to >> choose a different ORM lib. Time for some re-thinking! > > To be fair, the only reason the tests I quoted work when I switched to > Datamapper is because DM coincidentally (or not) uses the same > "valid?" method that AR does. Eventually you do have to hit your API. > I just like to hit it at the highest level that proves the behavior I > care about. Agreed in general. Just keep in mind that behaviour exists at more than one level. At the object level, behaviour == responsibility. If I'm a controller and my responsibility is to take a message from you, re-package it and hand it off to the appropriate model, then *that* is my behaviour. Cheers, David > -- > Have Fun, > Steve Eley (sfe...@gmail.com) > ESCAPE POD - The Science Fiction Podcast Magazine > http://www.escapepod.org > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users