From zach.lists at gmail.com Thu Aug 2 23:21:24 2007 From: zach.lists at gmail.com (Zach Moazeni) Date: Thu, 2 Aug 2007 23:21:24 -0400 Subject: [mocha-developer] Test errors without verification In-Reply-To: <1db558f00707260212t4a1d49cl924a4c4e39ea0fb3@mail.gmail.com> References: <01A5846A-D377-4FB0-8BE9-1D66C5AB7508@gmail.com> <1db558f00707260212t4a1d49cl924a4c4e39ea0fb3@mail.gmail.com> Message-ID: If anyone else feels these pains, I've written a monkey patch (ripped off from Hardmock) that will ensure both the verification and the user's teardown at http://www.simplechatter.com/2007/8/3/mocha-and- forcing-verification Mostly posting for archiving purposes. Thanks for the great mocking library, guys. -Zach On Jul 26, 2007, at 5:12 AM, James Mead wrote: > Hi Zach, > > On 26/07/07, Zach Moazeni wrote: >> >> I'm not sure if this is by design, but I've stumbled across this a >> few times trying to debug my own tests. If an assertion fails the >> test, and a missing mock expectation was to blame, the test's >> failure / error messages don't give enough info. > > > This is by design. In my mind a verification failure is analogous > to an > assertion failure. Test::Unit does not report multiple assertion > failures > per test, but reports the first failure. Failing fast seems like > the right > thing to do. At that point all bets are off and there is no point in > continuing. > > I wonder if the pain you are feeling is because you have too many > assertions > and/or expectations in each test. You might find the following article > interesting... > > http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html > > Thanks for taking the time to put a patch together, but at this > stage I'm > not convinced it's the way to go. > > -- > James. > http://blog.floehopper.org > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer From duncanbeevers at gmail.com Wed Aug 8 16:51:57 2007 From: duncanbeevers at gmail.com (Duncan Beevers) Date: Wed, 8 Aug 2007 13:51:57 -0700 Subject: [mocha-developer] Mocking Time, delegating to original object Message-ID: <6a2b4fd00708081351u652c95a4o9fa3c9bd90b29dc9@mail.gmail.com> In my Unit tests, I run into the all-too-common problem of Time.expects(:now) being called by Benchmark before the method is unmocked. Instead of messing around with the teardown order, I decided to modify the Expectation with a new method, .stops_mocking. Here are the changes I use, including a few monkey patches to push relevant objects down to where I want them, all wrapped up in a big ugly file. module Mocha class Mock def expects(method_name_or_hash, backtrace = nil, stub_method = nil) @stub_method = stub_method if method_name_or_hash.is_a?(Hash) then method_name_or_hash.each do |method_name, return_value| add_expectation(Expectation.new(self, method_name, backtrace).returns(return_value)) end else add_expectation(Expectation.new(self, method_name_or_hash, backtrace)) end end def stubs(method_name_or_hash, backtrace = nil, stub_method = nil) @stub_method = stub_method if method_name_or_hash.is_a?(Hash) then method_name_or_hash.each do |method_name, return_value| add_expectation(Stub.new(self, method_name, backtrace).returns(return_value)) end else add_expectation(Stub.new(self, method_name_or_hash, backtrace)) end end end class Expectation def delegates @return_values += ReturnValues.new(Delegator.new(self)) end alias :stops_mocking :delegates alias :stops_stubbing :delegates end class Delegator def initialize expectation @expectation = expectation end def evaluate @expectation.mock.stub_method.stubbee.send(@expectation.mock.stub_method.hidden_method) end end end class Object def expects(symbol) method = stubba_method.new(stubba_object, symbol) $stubba.stub(method) mocha.expects(symbol, caller, method) end def stubs(symbol) method = stubba_method.new(stubba_object, symbol) $stubba.stub(method) mocha.stubs(symbol, caller, method) end end Haven't tested this with anything other than Time.now, but thought I'd solicit the general opinion about this behavior. Usage is: Time.expects(:now).returns(mock_time).then.stops_mocking From jaime_cham at yahoo.com Mon Aug 13 16:52:30 2007 From: jaime_cham at yahoo.com (Jaime Cham) Date: Mon, 13 Aug 2007 13:52:30 -0700 (PDT) Subject: [mocha-developer] More flexible return values? Message-ID: <282085.97392.qm@web38702.mail.mud.yahoo.com> Thanks for the great library, we use Mocha extensibly on our test and love its readability and no-nonsense-ness. One thing that would be great, but that seems to be against some of the testing philosophy (which we don't quite deeply understand yet, so we can't come up with kosher alternatives) is the ability to be more flexible with the return values. Presently the only flexibility is to pass a Proc, but even this is going away. Ideally you could be as flexible as passing a block that received the call's parameters (which the Proc presently doesn't receive) so arbitrary logic could be used. Knowing that the more specific tests are the better, this flexibility allows for tests to be less brittle. More concretely, in our case we are using Mocha to mock and stub calls to a remote server. The code under test batches the calls for efficiency so that the exact request parameters are not known on each invokation, and the particular test wants to be independent of the batching parameters. Other cases might be that the number of possible return values is large given the inputs and can be expressed more succintly as a simple formula on the paramteters. Or the input and output must be ordered data but the order is not known or arbitrarily set by an intermediate component (e.g. a database). Or is there some other way that we are missing? thanks for elucidating us and for the great work on this library. Jaime Cham From justin at spiceworks.com Mon Aug 20 21:26:50 2007 From: justin at spiceworks.com (Justin Perkins) Date: Mon, 20 Aug 2007 20:26:50 -0500 Subject: [mocha-developer] mocking singletons Message-ID: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> How can I safely mock a singleton without the mocked method living on outside the scope of the test method? I've run into this problem with mocking methods on globals (gasp!) in the past by doing something like def mock_my_global original = $my_global $my_global.expects(:foo).returns('bar') yield $my_global = original end Is there something similar I can do for a singleton? Right now I have this: def mock_my_singleton m = mock("my singleton") m.expects(:foo).returns('bar') MySingleton.expects(:instance).returns(m) yield end Thanks for your help. -justin list mods: I sent a previous message to the list but my membership was pending so my message is too. This message is more concise than my previous one so please do not approve it :) From jamesmead44 at gmail.com Tue Aug 21 03:38:10 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 21 Aug 2007 08:38:10 +0100 Subject: [mocha-developer] mocking singletons In-Reply-To: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> Message-ID: <1db558f00708210038t7e5a6b0ere2058d7af144889c@mail.gmail.com> On 21/08/07, Justin Perkins wrote: > > How can I safely mock a singleton without the mocked method living on > outside the scope of the test method? This is one of the things Mocha takes care of for you in the context of a test method. I've run into this problem with mocking methods on globals (gasp!) in > the past by doing something like > > def mock_my_global > original = $my_global > $my_global.expects(:foo).returns('bar') > yield > $my_global = original > end > > Is there something similar I can do for a singleton? Right now I have > this: > > def mock_my_singleton > m = mock("my singleton") > m.expects(:foo).returns('bar') > MySingleton.expects(:instance).returns(m) > yield > end Do something like the following... def test_me m = mock("my singleton") m.expects(:foo).returns('bar') MySingleton.stubs(:instance).returns(m) # Mocha modifies the MySingleton#instance method at this point. # From now until the end of the test it will return the mock. # At the end of the test it will be reverted to its original implementation. end You don't need to explicitly revert the method to its original implementation - Mocha does it for you. list mods: I sent a previous message to the list but my membership > was pending so my message is too. This message is more concise than > my previous one so please do not approve it :) No problems. Thanks for letting me know. -- James. http://blog.floehopper.org From jamesmead44 at gmail.com Tue Aug 21 03:40:16 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 21 Aug 2007 08:40:16 +0100 Subject: [mocha-developer] Mocking Time, delegating to original object In-Reply-To: <6a2b4fd00708081351u652c95a4o9fa3c9bd90b29dc9@mail.gmail.com> References: <6a2b4fd00708081351u652c95a4o9fa3c9bd90b29dc9@mail.gmail.com> Message-ID: <1db558f00708210040n64b36bd5y8d733a42d2924a5d@mail.gmail.com> Thanks for your email. I'm sorry nobody on the list has replied - I've been really busy at work recently. I'll try and reply properly as soon as I can. -- James. http://blog.floehopper.org From jamesmead44 at gmail.com Tue Aug 21 03:40:41 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 21 Aug 2007 08:40:41 +0100 Subject: [mocha-developer] More flexible return values? In-Reply-To: <282085.97392.qm@web38702.mail.mud.yahoo.com> References: <282085.97392.qm@web38702.mail.mud.yahoo.com> Message-ID: <1db558f00708210040o5ec1262asc7500cf6244069b3@mail.gmail.com> Thanks for your email. I'm sorry nobody on the list has replied - I've been really busy at work recently. I'll try and reply properly as soon as I can. -- James. http://blog.floehopper.org From j at jonathanleighton.com Tue Aug 21 04:45:11 2007 From: j at jonathanleighton.com (Jonathan Leighton) Date: Tue, 21 Aug 2007 09:45:11 +0100 Subject: [mocha-developer] mocking singletons In-Reply-To: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> Message-ID: <1187685911.5699.0.camel@cho> On Mon, 2007-08-20 at 20:26 -0500, Justin Perkins wrote: > How can I safely mock a singleton without the mocked method living on > outside the scope of the test method? This is how I did it: http://jonathanleighton.com/blog/testing-singleton-classes From justin at spiceworks.com Tue Aug 21 13:28:15 2007 From: justin at spiceworks.com (Justin Perkins) Date: Tue, 21 Aug 2007 12:28:15 -0500 Subject: [mocha-developer] mocking singletons In-Reply-To: <1187685911.5699.0.camel@cho> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> <1187685911.5699.0.camel@cho> Message-ID: <40A0CB94-4483-4B40-931E-BE774D937BFF@spiceworks.com> > On Aug 21, 2007, at 3:45 AM, Jonathan Leighton wrote: > This is how I did it: > http://jonathanleighton.com/blog/testing-singleton-classes Can I define a teardown method in the test_helper or would your solution require a per-test-case teardown method to reload the singleton? -justin From justin at spiceworks.com Tue Aug 21 14:13:06 2007 From: justin at spiceworks.com (Justin Perkins) Date: Tue, 21 Aug 2007 13:13:06 -0500 Subject: [mocha-developer] mocking singletons In-Reply-To: <1db558f00708210038t7e5a6b0ere2058d7af144889c@mail.gmail.com> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> <1db558f00708210038t7e5a6b0ere2058d7af144889c@mail.gmail.com> Message-ID: On Aug 21, 2007, at 2:38 AM, James Mead wrote: > > This is one of the things Mocha takes care of for you in the > context of a > test method. That's what I thought but I was getting weird behavior when I ran all the tests that led me to believe the mocked method was lingering around. > MySingleton.stubs(:instance).returns(m) That was it. As soon as I used stubs instead of expects, everything works fine. I believe that when you use expects on a singleton, the mock lingers after the test is complete. -justin From j at jonathanleighton.com Wed Aug 22 04:29:13 2007 From: j at jonathanleighton.com (Jonathan Leighton) Date: Wed, 22 Aug 2007 09:29:13 +0100 Subject: [mocha-developer] mocking singletons In-Reply-To: <40A0CB94-4483-4B40-931E-BE774D937BFF@spiceworks.com> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> <1187685911.5699.0.camel@cho> <40A0CB94-4483-4B40-931E-BE774D937BFF@spiceworks.com> Message-ID: <1187771354.5728.1.camel@cho> On Tue, 2007-08-21 at 12:28 -0500, Justin Perkins wrote: > > On Aug 21, 2007, at 3:45 AM, Jonathan Leighton wrote: > > This is how I did it: > > http://jonathanleighton.com/blog/testing-singleton-classes > > Can I define a teardown method in the test_helper or would your > solution require a per-test-case teardown method to reload the > singleton? I'm not sure why you'd want to do that? You'd only need to "reload" the Singleton when you are testing it, not in every single test. Maybe I've misunderstood something... Jon From jamesmead44 at gmail.com Wed Aug 22 05:00:01 2007 From: jamesmead44 at gmail.com (James Mead) Date: Wed, 22 Aug 2007 10:00:01 +0100 Subject: [mocha-developer] mocking singletons In-Reply-To: References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> <1db558f00708210038t7e5a6b0ere2058d7af144889c@mail.gmail.com> Message-ID: <1db558f00708220200k2a10158q77c391867a0b35a8@mail.gmail.com> On 21/08/07, Justin Perkins wrote: > > > On Aug 21, 2007, at 2:38 AM, James Mead wrote: > > > > This is one of the things Mocha takes care of for you in the > > context of a > > test method. > > That's what I thought but I was getting weird behavior when I ran all > the tests that led me to believe the mocked method was lingering around. > > > MySingleton.stubs(:instance).returns(m) > > That was it. As soon as I used stubs instead of expects, everything > works fine. I believe that when you use expects on a singleton, the > mock lingers after the test is complete. That sounds wrong. "expects" should work as well. You may have found a bug. If you get the chance can you try and distill the failing scenario down to the smallest self-contained test you can and post it too the list. Thanks. -- James. http://blog.floehopper.org From dchelimsky at gmail.com Wed Aug 22 10:46:44 2007 From: dchelimsky at gmail.com (David Chelimsky) Date: Wed, 22 Aug 2007 09:46:44 -0500 Subject: [mocha-developer] mock framework ethics question Message-ID: <57c63afe0708220746m2bca12a8m8261530b9d267a73@mail.gmail.com> Hi James, Jim, and everyone else who's listening. I've been investigating an interesting bug related to mocks and rails AssociationProxies. See http://rubyforge.org/tracker/?func=detail&atid=3149&aid=12547&group_id=797 for details. The crux is that if you do this (rspec mock syntax): obj.should_receive(:msg).with(mock_of_a_model) and the implementation does this: obj.msg(containing_model.association_proxy) the expectation fails. This is because the comparison that rspec mocks make is: expected == actual which, in this case ends up being: mock_of_a_model == association_proxy As it turns out, mocha and flexmock do this the same way, which means that this will fail in any of the three frameworks. So here's the mock-ethics question of the week: Should the comparison be changed to: actual == expected or actual == expected || expected == actual or ... neither? I have arguments for all three - I'd like to hear your thoughts. Cheers, David From justin at spiceworks.com Wed Aug 22 12:37:34 2007 From: justin at spiceworks.com (Justin Perkins) Date: Wed, 22 Aug 2007 11:37:34 -0500 Subject: [mocha-developer] mocking singletons In-Reply-To: <1187771354.5728.1.camel@cho> References: <4E4E5A84-D1AE-46D2-B3EE-BCB515622607@spiceworks.com> <1187685911.5699.0.camel@cho> <40A0CB94-4483-4B40-931E-BE774D937BFF@spiceworks.com> <1187771354.5728.1.camel@cho> Message-ID: <09FE1BCE-00BF-4C93-9A83-5522489F0000@spiceworks.com> On Aug 22, 2007, at 3:29 AM, Jonathan Leighton wrote: > I'm not sure why you'd want to do that? You'd only need to "reload" > the > Singleton when you are testing it, not in every single test. Maybe > I've > misunderstood something... In every test where I was mocking my singleton I would have to add an additional teardown method, since I'm retrofitting existing code to mock the singleton this would require more work than I think is necessary. Maybe I'm just misunderstanding the implementation? -justin From felix.klee at inka.de Wed Aug 29 07:33:38 2007 From: felix.klee at inka.de (Felix E. Klee) Date: Wed, 29 Aug 2007 13:33:38 +0200 Subject: [mocha-developer] Undefined method stub Message-ID: <87y7fupobx.wl%felix.klee@inka.de> When I try to execute the following example, I get an error message: /usr/local/lib/ruby/gems/1.8/gems/mocha-0.5.4/lib/mocha/object.rb:40: in `expects': undefined method `stub' for nil:NilClass (NoMethodError) from test8.rb:5 What could be the reason? I tried with the latest Mocha Ruby gem, and I also tried it with the Rails plugin. The example: require 'rubygems' require 'mocha' some_time = Time.at(0) Time.expects(:now).returns(some_time) puts Time.now -- Felix E. Klee Jabber/Google Talk: feklee at jabber.org, SIP: 9779619 at sipgate.de ICQ: 158124695, Yahoo!: feklee, AIM: felix.klee at inka.de Gizmo: felixklee, Skype: felix.klee From felix.klee at inka.de Wed Aug 29 07:37:17 2007 From: felix.klee at inka.de (Felix E. Klee) Date: Wed, 29 Aug 2007 13:37:17 +0200 Subject: [mocha-developer] Undefined method stub Message-ID: <87wsvepo5u.wl%felix.klee@inka.de> When I try to execute the following example, I get an error message: /usr/local/lib/ruby/gems/1.8/gems/mocha-0.5.4/lib/mocha/object.rb:40: in `expects': undefined method `stub' for nil:NilClass (NoMethodError) from test8.rb:5 What could be the reason? I tried with the latest Mocha Ruby gem, and I also tried it with the Rails plugin. The example: require 'rubygems' require 'mocha' some_time = Time.at(0) Time.expects(:now).returns(some_time) puts Time.now -- Felix E. Klee Jabber/Google Talk: feklee at jabber.org, SIP: 9779619 at sipgate.de ICQ: 158124695, Yahoo!: feklee, AIM: felix.klee at inka.de Gizmo: felixklee, Skype: felix.klee From jamesmead44 at gmail.com Wed Aug 29 09:29:58 2007 From: jamesmead44 at gmail.com (James Mead) Date: Wed, 29 Aug 2007 14:29:58 +0100 Subject: [mocha-developer] Undefined method stub In-Reply-To: <87y7fupobx.wl%felix.klee@inka.de> References: <87y7fupobx.wl%felix.klee@inka.de> Message-ID: <1db558f00708290629q13210d9bm80f242b8e58ffcd2@mail.gmail.com> You need to try it from within a test framework like Test::Unit or RSpec. Something like this... require 'test/unit' require 'rubygems' require 'mocha' class ExampleTest < Test::Unit::TestCase def test_time_now some_time = Time.at(0) Time.expects(:now).returns(some_time) puts Time.now end end -- James. http://blog.floehopper.org From felix.klee at inka.de Wed Aug 29 09:38:07 2007 From: felix.klee at inka.de (Felix E. Klee) Date: Wed, 29 Aug 2007 15:38:07 +0200 Subject: [mocha-developer] Undefined method stub In-Reply-To: <1db558f00708290629q13210d9bm80f242b8e58ffcd2@mail.gmail.com> References: <87y7fupobx.wl%felix.klee@inka.de> <1db558f00708290629q13210d9bm80f242b8e58ffcd2@mail.gmail.com> Message-ID: <87tzqipikg.wl%felix.klee@inka.de> At Wed, 29 Aug 2007 14:29:58 +0100, James Mead wrote: > You need to try it from within a test framework like Test::Unit or > RSpec. Something like this... This works, but if a test framework is necessary, then Mocha seems to be uninteresting for me: I want to use it when demoing a Ruby on Rails application, i.e. in a development environment, or maybe - during the alpha phase - in a production environment. Should I better forge my own Time.now function? -- Felix E. Klee Jabber/Google Talk: feklee at jabber.org, SIP: 9779619 at sipgate.de ICQ: 158124695, Yahoo!: feklee, AIM: felix.klee at inka.de Gizmo: felixklee, Skype: felix.klee From jamesmead44 at gmail.com Wed Aug 29 09:51:35 2007 From: jamesmead44 at gmail.com (James Mead) Date: Wed, 29 Aug 2007 14:51:35 +0100 Subject: [mocha-developer] Undefined method stub In-Reply-To: <87tzqipikg.wl%felix.klee@inka.de> References: <87y7fupobx.wl%felix.klee@inka.de> <1db558f00708290629q13210d9bm80f242b8e58ffcd2@mail.gmail.com> <87tzqipikg.wl%felix.klee@inka.de> Message-ID: <1db558f00708290651k29015a8bn179f41cd2a54dbfe@mail.gmail.com> On 29/08/2007, Felix E. Klee wrote: > > This works, but if a test framework is necessary, then Mocha seems to be > uninteresting for me: I want to use it when demoing a Ruby on Rails > application, i.e. in a development environment, or maybe - during the > alpha phase - in a production environment. > > Should I better forge my own Time.now function? > This isn't really what Mocha was intended for - it's really intended for doing "interation-based testing" [1]. The main technical reason you need to use it within a test is that it hooks into the point at which each test ends to put any class it has modified back into its original state. You could look at Mocha::TestCaseAdapter class and write your own equivalent, but if the only thing you need it for is stubbing Time.now - I'd recommend you create your own fake version of Time.now. I hope that helps. 1. http://www.martinfowler.com/articles/mocksArentStubs.html -- James. http://blog.floehopper.org http://tumble.floehopper.org From felix.klee at inka.de Wed Aug 29 10:01:20 2007 From: felix.klee at inka.de (Felix E. Klee) Date: Wed, 29 Aug 2007 16:01:20 +0200 Subject: [mocha-developer] Undefined method stub In-Reply-To: <1db558f00708290651k29015a8bn179f41cd2a54dbfe@mail.gmail.com> References: <87y7fupobx.wl%felix.klee@inka.de> <1db558f00708290629q13210d9bm80f242b8e58ffcd2@mail.gmail.com> <87tzqipikg.wl%felix.klee@inka.de> <1db558f00708290651k29015a8bn179f41cd2a54dbfe@mail.gmail.com> Message-ID: <87sl62phhr.wl%felix.klee@inka.de> At Wed, 29 Aug 2007 14:51:35 +0100, James Mead wrote: > I hope that helps. It does, thanks! Felix -- Felix E. Klee Jabber/Google Talk: feklee at jabber.org, SIP: 9779619 at sipgate.de ICQ: 158124695, Yahoo!: feklee, AIM: felix.klee at inka.de Gizmo: felixklee, Skype: felix.klee