Hi I''m trying to spec a call to error_messages_for to avoid stubbing out whole models. Something like this: context "A rendered calculate_quote view" do setup do @form = mock("form") assigns[:form] = @form end specify "should render the error messages" do <SOMETHING>.should_receive(:error_messages_for).with (''form'', :anything) render ''gap/calculate_quote'' end end What can I put as <SOMETHING>? Thanks... Ashley
On 3/21/07, Ashley Moran <work at ashleymoran.me.uk> wrote:> Hi > > I''m trying to spec a call to error_messages_for to avoid stubbing out > whole models. Something like this: > > context "A rendered calculate_quote view" do > setup do > @form = mock("form") > assigns[:form] = @form > end > > specify "should render the error messages" do > <SOMETHING>.should_receive(:error_messages_for).with > (''form'', :anything) > render ''gap/calculate_quote'' > end > end > > What can I put as <SOMETHING>?"Danger, danger, Will Robinson!" The fact that you have to ask this question is a sign that you probably shouldn''t be doing this. The answer lies in AR internals, which is stuff you really shouldn''t be mocking. Imagine that you do this, and a new version of rails implements this differently. You may start getting a bunch of failing integration tests w/o failing isolation tests and they''ll be very difficult to track down. .02 David> > Thanks... > Ashley > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Mar 21, 2007, at 5:12 pm, David Chelimsky wrote:> "Danger, danger, Will Robinson!" > > The fact that you have to ask this question is a sign that you > probably shouldn''t be doing this. The answer lies in AR internals, > which is stuff you really shouldn''t be mocking.David, When I gave up reading through the Rails API and code I had started to come to that conclusion already. Unfortunately I''ve redefined error_messages_for to give more control over the output (why it takes so few parameters, I don''t know). Now, I can spec my new helper method easily enough, but that doesn''t help if I can''t test if it gets called. It''s one thing testing the output of a currency formatter, it''s another thing to have to copy and paste tests for multi-line HTML every time it''s used.> Imagine that you do this, and a new version of rails implements this > differently. You may start getting a bunch of failing integration > tests w/o failing isolation tests and they''ll be very difficult to > track down.Which makes me wonder... why is it so hidden? I know it''s nice to have some Ruby magic so I can call helper methods like "<%= my_method (''blah'') %>" in the view source, but really, I''d be just as happy writing "<%= page.my_method(''blah'') %>" if it made it more transparent The only solution I can think of is to find whatever trainwreck takes me from @controller to the thing with error_messages_for, and write an assumption spec for its current implementation, so that if and when that changes, I''m notified of it. The only alternative I can see is lengthy, redundant should-have_tag specs. What do you think of this as a compromise? Ashley
On 3/21/07, Ashley Moran <work at ashleymoran.me.uk> wrote:> > On Mar 21, 2007, at 5:12 pm, David Chelimsky wrote: > > > "Danger, danger, Will Robinson!" > > > > The fact that you have to ask this question is a sign that you > > probably shouldn''t be doing this. The answer lies in AR internals, > > which is stuff you really shouldn''t be mocking. > > David, > > When I gave up reading through the Rails API and code I had started > to come to that conclusion already. Unfortunately I''ve redefined > error_messages_for to give more control over the output (why it takes > so few parameters, I don''t know).This is an interesting case because the behaviour you want to describe is no longer in your app - it''s actually new behaviour in Rails itself (in your patch of rails). What I prefer to do in this case is patch the rails tests as well, rather than adding tests to my app(s). I keep a set of patches around that patch both tests and implementation and whenever I install rails in a project, I run these patches and don''t worry about it in the examples for my app. WDYT?> Now, I can spec my new helper > method easily enough, but that doesn''t help if I can''t test if it > gets called. It''s one thing testing the output of a currency > formatter, it''s another thing to have to copy and paste tests for > multi-line HTML every time it''s used. > > > > Imagine that you do this, and a new version of rails implements this > > differently. You may start getting a bunch of failing integration > > tests w/o failing isolation tests and they''ll be very difficult to > > track down. > > Which makes me wonder... why is it so hidden? I know it''s nice to > have some Ruby magic so I can call helper methods like "<%= my_method > (''blah'') %>" in the view source, but really, I''d be just as happy > writing "<%= page.my_method(''blah'') %>" if it made it more transparentRails is all about opacity. I re-learn that lesson nearly every day.> The only solution I can think of is to find whatever trainwreck takes > me from @controller to the thing with error_messages_for, and write > an assumption spec for its current implementation, so that if and > when that changes, I''m notified of it. The only alternative I can > see is lengthy, redundant should-have_tag specs. What do you think > of this as a compromise?Well, it doesn''t make me want to jump for joy, but I might choose to do it this way anyhow. Lesser of many evils and all. David> > Ashley > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 22 Mar 2007, at 17:52, David Chelimsky wrote:> This is an interesting case because the behaviour you want to describe > is no longer in your app - it''s actually new behaviour in Rails itself > (in your patch of rails).Well I added the code to ApplicationHelper, so I guess the tests still belong in my app, even if they override some Rails magic (actually, maybe the thing I need to test is that it DOES override the Rails magic but let''s not go there...)> Rails is all about opacity. I re-learn that lesson nearly every day.Within Rails, there is a much smaller and cleaner framework struggling to get out?> Well, it doesn''t make me want to jump for joy, but I might choose to > do it this way anyhow. Lesser of many evils and all.Eventually I gave up and did this. I added the following to my controller spec: context "ASSUMPTION (about the next spec): the controller" do specify "should have respond to template and return a template that responds to error_messages_for" do @controller.should respond_to(:template) @controller.template.should respond_to(:error_messages_for) end end context "A rendered calculate_quote view with an invalid form" do ... specify "should render the error messages" do @controller.template.should_receive(:error_messages_for).with (''form'', :anything).and_return("<div>ERRORS</div>") render ''gap/calculate_quote'' response.should have_tag("div", :text => "ERRORS") end end Which I think catches it. I don''t think given the current Rails architecture that there''s a cleaner way. Thanks Ashley