Lenny Marks
2009-Dec-01 16:46 UTC
[rspec-users] should_receive(:x).at_most/exactly... ignored when method is previously stubbed?
I''ve always used the idiom of stub collaborations in a before block and then focus in specific examples with should_receive. (e.g. should_receive takes presence over stub). I was just attempting to write an example for caching behavior and ran into something counter- intuitive, at least IMHO. See the following(contrived) example. class ExpensiveOperation def self.lookup(question) "This goes to the database" end end class UsesExpensiveOperation def initialize @cache = {} end def answer_for(question) # oops, this is broken, it was supposed to be cached # @cache[question] ||= ExpensiveOperation.lookup(question) @cache[question] = ExpensiveOperation.lookup(question) end end describe "suprising behavior" do before do @object = UsesExpensiveOperation.new ExpensiveOperation.stub(:lookup).and_return(''whatever'') end it "should fail because I''m specifying that lookup should be called at most one time, but that''s not true" do ExpensiveOperation .should_receive(:lookup).at_most(:once).and_return(''an answer'') @object.answer_for("my question") @object.answer_for("my question") end end This seems dangerous to me. Assuming I hadn''t initially stubbed in the before block and everything worked as expected, if someone later stubs :lookup in the before block because they are adding new examples that don''t care about it, my explicit example becomes misleadingly useless. Does this surprise anyone else? -lenny
Lenny Marks
2009-Dec-01 17:39 UTC
[rspec-users] should_receive(:x).at_most/exactly... ignored when method is previously stubbed?
Forgot to mention: rspec 1.2.9 On Dec 1, 2009, at 11:46 AM, Lenny Marks wrote:> I''ve always used the idiom of stub collaborations in a before block > and then focus in specific examples with should_receive. (e.g. > should_receive takes presence over stub). I was just attempting to > write an example for caching behavior and ran into something counter- > intuitive, at least IMHO. See the following(contrived) example. > > class ExpensiveOperation > def self.lookup(question) > "This goes to the database" > end > end > > class UsesExpensiveOperation > def initialize > @cache = {} > end > > def answer_for(question) > # oops, this is broken, it was supposed to be cached > # @cache[question] ||= ExpensiveOperation.lookup(question) > @cache[question] = ExpensiveOperation.lookup(question) > end > end > > describe "suprising behavior" do > before do > @object = UsesExpensiveOperation.new > > ExpensiveOperation.stub(:lookup).and_return(''whatever'') > end > > it "should fail because I''m specifying that lookup should be > called at most one time, but that''s not true" do > > ExpensiveOperation > .should_receive(:lookup).at_most(:once).and_return(''an answer'') > > @object.answer_for("my question") > @object.answer_for("my question") > end > > end > > This seems dangerous to me. Assuming I hadn''t initially stubbed in > the before block and everything worked as expected, if someone later > stubs :lookup in the before block because they are adding new > examples that don''t care about it, my explicit example becomes > misleadingly useless. > > Does this surprise anyone else? > > -lenny > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Ashley Moran
2009-Dec-01 18:24 UTC
[rspec-users] should_receive(:x).at_most/exactly... ignored when method is previously stubbed?
On Dec 01, 2009, at 4:46 pm, Lenny Marks wrote:> This seems dangerous to me. Assuming I hadn''t initially stubbed in the before block and everything worked as expected, if someone later stubs :lookup in the before block because they are adding new examples that don''t care about it, my explicit example becomes misleadingly useless. > > Does this surprise anyone else?Hi Lenny Yes it does, so much so that I filed a ticket[1] :) Well, I think it''s the same issue. If so, maybe you''ll find the discussion between me and David useful. HTH Ashley [1] https://rspec.lighthouseapp.com/projects/5645/tickets/618-exactlyntimes-incorrectly-failing-for-n-actual -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran
Lenny Marks
2009-Dec-01 19:34 UTC
[rspec-users] should_receive(:x).at_most/exactly... ignored when method is previously stubbed?
On Dec 1, 2009, at 1:24 PM, Ashley Moran wrote:> > On Dec 01, 2009, at 4:46 pm, Lenny Marks wrote: > >> This seems dangerous to me. Assuming I hadn''t initially stubbed in >> the before block and everything worked as expected, if someone >> later stubs :lookup in the before block because they are adding new >> examples that don''t care about it, my explicit example becomes >> misleadingly useless. >> >> Does this surprise anyone else? > > Hi Lenny > > Yes it does, so much so that I filed a ticket[1] :) > > Well, I think it''s the same issue. If so, maybe you''ll find the > discussion between me and David useful. > > HTH > > Ashley > > [1] https://rspec.lighthouseapp.com/projects/5645/tickets/618-exactlyntimes-incorrectly-failing-for-n-actual >Thanks Ashley. I added my 2 cents to the ticket. -lenny
Ashley Moran
2009-Dec-01 19:49 UTC
[rspec-users] should_receive(:x).at_most/exactly... ignored when method is previously stubbed?
On Dec 01, 2009, at 7:34 pm, Lenny Marks wrote:> Thanks Ashley. I added my 2 cents to the ticket.Just had a look over your comments. It''s a complicated issue... I hope David can reconcile it. I''m not sure what the best solution is. Ashley -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran