Paul Butcher
2006-Sep-22 23:22 UTC
[mocha-developer] I''m misunderstanding how stubs works
We''re still just starting out with Mocha/Stubba, so please forgive any newbie errors. I''m using "stubs" to test some realtime functions, to control exactly which time is returned from Time.now. I would expect the following test to pass: def test_two_stubs t = Time.now - 60 Time.stubs(:now).returns(t) start_time = Time.now t += 20 Time.stubs(:now).returns(t) end_time = Time.now assert_equal end_time - start_time, 20 end But it fails with: 1) Failure: test_two_stubs(MochaTest) [mochatest.rb:19]: <0.0> expected but was <20>. I can create a test which works as I intend: def test_lambda t = Time.now - 60 Time.stubs(:now).returns(lambda { t }) start_time = Time.now t += 20 end_time = Time.now assert_equal end_time - start_time, 20 end But I''d be interested to understand why the first version doesn''t. Thanks in advance for any help you can offer! ------------------------------------------------- Paul Butcher CTO RE5ULT Limited 74 Eden Street, Cambridge CB1 1EL http://www.82ask.com/ Office: +44 (0) 1223 309080 Mobile: +44 (0) 7740 857648 Email: paul at 82ask.com MSN: paul at paulbutcher.com AIM: paulrabutcher Skype: paulrabutcher LinkedIn: https://www.linkedin.com/in/paulbutcher ------------------------------------------------- 82ASK: text any question to 82ASK (82275) and get the answer in minutes. Visit www.82ask.com to get your first 2 questions answered for free.
On 23/09/06, Paul Butcher <paul at 82ask.com> wrote:> > I''m using "stubs" to test some realtime functions, to control exactly > which > time is returned from Time.now. I would expect the following test to pass: > > def test_two_stubs > t = Time.now - 60 > Time.stubs(:now).returns(t) > > start_time = Time.now > > t += 20 > Time.stubs(:now).returns(t) > > end_time = Time.now > > assert_equal end_time - start_time, 20 > end > > But it fails with: > > 1) Failure: > test_two_stubs(MochaTest) [mochatest.rb:19]: > <0.0> expected but was > <20>. > > I can create a test which works as I intend: > > def test_lambda > t = Time.now - 60 > Time.stubs(:now).returns(lambda { t }) > > start_time = Time.now > > t += 20 > > end_time = Time.now > > assert_equal end_time - start_time, 20 > end > > But I''d be interested to understand why the first version doesn''t. >Hi Paul, The first version doesn''t work, because the second stub expectation doesn''t replace the first. When the end_time call to Time.now comes in, it is matched to the first expectation and so returns the first value of t. I agree that this is not what you would expect and it''s been on my todo list for a while. It hasn''t made it to the top, because there are ways round it as you have demonstrated. I would probably use the same technique as you, but you might be interested to see a couple of other possibilities... The first one makes use of the fact that expectations match based on parameters as well as method name. Even though Time.now doesn''t take any parameters, you can supply a block which returns true or false depending on whether it should match... def test_two_stubs_with_parameter_block t = Time.now - 60 context = :start Time.stubs(:now).with { context == :start }.returns(t) Time.stubs(:now).with { context == :finish }.returns(t + 20) start_time = Time.now context = :finish end_time = Time.now assert_equal end_time - start_time, 20 end The second one makes use of a recent change in HEAD (not released in the gem), which allows you to specify consecutive return values. Although this won''t be useful if there are many calls to Time.now... def test_two_stubs_consecutive_return_values t = Time.now - 60 Time.stubs(:now).returns(t, t + 20) start_time = Time.now end_time = Time.now assert_equal end_time - start_time, 20 end I hope that helps. -- James. http://blog.floehopper.org -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/mocha-developer/attachments/20060923/4af3a085/attachment.html
Paul Butcher
2006-Sep-24 10:38 UTC
[mocha-developer] I''m misunderstanding how stubs works
James Mead wrote:> The first version doesn''t work, because the second stub expectation > doesn''t replace the first. When the end_time call to Time.now comes in, > it is matched to the first expectation and so returns the first value > of t. I agree that this is not what you would expect and it''s been on > my todo list for a while. It hasn''t made it to the top, because there > are ways round it as you have demonstrated. I would probably use the > same technique as you, but you might be interested to see a couple of > other possibilities...Cool. Thanks James - that makes perfect sense. Glad to see that I''m not being stupid ;-) Cheers! ------------------------------------------------- Paul Butcher CTO RE5ULT Limited 74 Eden Street, Cambridge CB1 1EL http://www.82ask.com/ Office: +44 (0) 1223 309080 Mobile: +44 (0) 7740 857648 Email: paul at 82ask.com MSN: paul at paulbutcher.com AIM: paulrabutcher Skype: paulrabutcher LinkedIn: https://www.linkedin.com/in/paulbutcher ------------------------------------------------- 82ASK: text any question to 82ASK (82275) and get the answer in minutes. Visit www.82ask.com to get your first 2 questions answered for free.