pangel
2007-Nov-01 10:26 UTC
[rspec-users] Can''t use #exactly when #and_return influences it.
I want my class Reader to loop on the content of its Stack until false is returned. I also want an optional argument to exist that limits how many times the stack will be read, even if some elements are left. I was trying to spec this last bit but ended up on a false positive. Hope the example will be clear enough: #spec_reader.rb describe Reader do it "should stop reading items when called with a limit" do @stack = mock(Stack) Stack.should_receive(:new).and_return(@stack) @stack.should_receive(:read).exactly(3).times.and_return(2,4,1,5,3,1,false) @reader = Reader.new @reader.read_stack(3) end end # reader.rb class Reader def initialize @stack = Stack.new end def read_stack(limit = 0) #0 = read until false is returned while val = @stack.read # Not implemented on purpose! # return if limit == 0 # limit -= limit ... end end So the test should fail, because the use of the limit argument has not been implemented yet and #read gets called 7 times. But the test actually passes. I looked into it a bit and it seems that number of arguments in #and_return overrides the arguments of #exactly. Did I misunderstand the point of #exactly or should I build my code differently so that the value returned by #and_return does not influence how many times #read is called? -- View this message in context: http://www.nabble.com/Can%27t-use--exactly-when--and_return-influences-it.-tf4730412.html#a13526196 Sent from the rspec-users mailing list archive at Nabble.com.
David Chelimsky
2007-Nov-01 10:54 UTC
[rspec-users] Can''t use #exactly when #and_return influences it.
On Nov 1, 2007 5:26 AM, pangel <pangel.neu at gmail.com> wrote:> > I want my class Reader to loop on the content of its Stack until false is > returned. I also want an optional argument to exist that limits how many > times the stack will be read, even if some elements are left. I was trying > to spec this last bit but ended up on a false positive. > > > Hope the example will be clear enough: > > #spec_reader.rb > describe Reader do > it "should stop reading items when called with a limit" do > @stack = mock(Stack) > Stack.should_receive(:new).and_return(@stack) > > @stack.should_receive(:read).exactly(3).times.and_return(2,4,1,5,3,1,false)This should probably not be allowed.> > @reader = Reader.new > @reader.read_stack(3) > end > end > > # reader.rb > class Reader > def initialize > @stack = Stack.new > end > > def read_stack(limit = 0) #0 = read until false is returned > while val = @stack.read > # Not implemented on purpose! > # return if limit == 0 > # limit -= limit > ... > end > end > > So the test should fail, because the use of the limit argument has not been > implemented yet and #read gets called 7 times. But the test actually passes. > I looked into it a bit and it seems that number of arguments in #and_return > overrides the arguments of #exactly. > > Did I misunderstand the point of #exactly or should I build my code > differently so that the value returned by #and_return does not influence how > many times #read is called?I think this is a bug, but the question is - what is the bug? I think the mock should complain when you set exactly(n).times and then give it a different number of return values. WDYT?
pangel
2007-Nov-01 12:54 UTC
[rspec-users] Can''t use #exactly when #and_return influences it.
Yes this would make sense, or the mock could just stop sending the values as soon as it does not receive messages anymore. Obviously I prefer this second behaviour because it would, I think, make my specs work correctly. But from a logical point of view as well, this works for me. If the mock complains when there''s more return values than expected calls, it would reduce the amount of errors, but it''s usually a one-liner so the risk is not that great. On the other hand the second possibility (just stop sending values) would introduce a flexibility that might be handy in some situations. I''m quite a beginner in both ruby and TDD/BDD concepts so I feel like there''s a lot I just don''t have a full grasp on anyway. Regarding my specs do you think I should structure the whole thing differently? David Chelimsky-2 wrote:> > On Nov 1, 2007 5:26 AM, pangel <pangel.neu at gmail.com> wrote: >> >> I want my class Reader to loop on the content of its Stack until false is >> returned. I also want an optional argument to exist that limits how many >> times the stack will be read, even if some elements are left. I was >> trying >> to spec this last bit but ended up on a false positive. >> >> >> Hope the example will be clear enough: >> >> #spec_reader.rb >> describe Reader do >> it "should stop reading items when called with a limit" do >> @stack = mock(Stack) >> Stack.should_receive(:new).and_return(@stack) >> >> @stack.should_receive(:read).exactly(3).times.and_return(2,4,1,5,3,1,false) > > This should probably not be allowed. > >> >> @reader = Reader.new >> @reader.read_stack(3) >> end >> end >> >> # reader.rb >> class Reader >> def initialize >> @stack = Stack.new >> end >> >> def read_stack(limit = 0) #0 = read until false is returned >> while val = @stack.read >> # Not implemented on purpose! >> # return if limit == 0 >> # limit -= limit >> ... >> end >> end >> >> So the test should fail, because the use of the limit argument has not >> been >> implemented yet and #read gets called 7 times. But the test actually >> passes. >> I looked into it a bit and it seems that number of arguments in >> #and_return >> overrides the arguments of #exactly. >> >> Did I misunderstand the point of #exactly or should I build my code >> differently so that the value returned by #and_return does not influence >> how >> many times #read is called? > > I think this is a bug, but the question is - what is the bug? I think > the mock should complain when you set exactly(n).times and then give > it a different number of return values. > > WDYT? > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > >-- View this message in context: http://www.nabble.com/Can%27t-use--exactly-when--and_return-influences-it.-tf4730412.html#a13528094 Sent from the rspec-users mailing list archive at Nabble.com.