"Mark Wilden" <m...@mwilden.com> writes: > On Thu, Dec 11, 2008 at 4:33 AM, Andrew Premdas <aprem...@gmail.com> wrote: > > it "should find all posts" do > Post.should_receive(:find).with(:all).and_return([...@post]) > do_get > end > > Now this last spec "should find all posts" is nosy is far as I'm > concerned in that its specifying how the model should get all the > posts (i.e. white box testing) rather than checking the result i.e. > that its got @post back. So now if I change the model so that > "all posts" is for example "all posts in last year" because there is > a new business rule that we don't show posts over a year old > then my controller spec fails. > > I think this is probably correct as is. > > When specing a controller, it's correct BDD to specify how it interacts with > other objects. If the controller itself wants all posts in the > last year, it's OK to test that. The fact that only this year's posts are of > interest is a presentation issue - it's not an essential > characteristic of the data. It's not the model's job to decide that all > clients should get back posts in the last year, and hence that's > what its find method should return. > > All business rules don't reside in the model. As soon as you say "we don't > SHOW posts over a year," you're talking about a presentation > rule, not a model rule. Controllers mediate between data and screen - they're > responsible for getting the data to be shown. That code should > exist in the controller and be tested there. > > On the other hand, the controller should not necessarily be responsible for > defining what constitutes "all posts in the last year." That > should very likely be a named scope. > > This is all just my humble opinion, of course, and might be utter rubbish in > any particular real world situation. > > ///ark > > _______________________________________________ > rspec-users mailing list > rspec-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
I agree with this. You generally don't want to screw with the meaning of AR::Base.find. That's really only for situations where you want some uniform, transparent behavior (acts_as_versioned, acts_as_paranoid, etc). The view shouldn't really care about this stuff either...it should just take a list of posts and display them. It's up to the controller to ask the model for what it wants to push to the view. So your finder can be something like Post.since(1.year.ago) or whatever. Andrew, I've noticed a theme in your posts that suggests you feel you needn't ever change controller specs. That's just not true. Models are a distilled representation of the domain, and controllers give meaning to it in the context of the application you're working on. Models are what your app *is* and controllers are what your app *does*. When you change what your app does, you're going to have to change some specs and production code along with it. Keep in mind that if you went with a state-based test, you would *still* have to modify the controller spec. It wouldn't be good enough to expect a post to be displayed. You'd have to create a post with a created_at of over a year ago, and one within the last year, and expect that the former is not shown while the latter is. Also, I'd like to point out that if you *really* wanted Post.find(:all) to only return posts in the last year, you wouldn't actually have to change the controller spec :) You would just have to write a model spec for that behavior. Pat _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users