From duncanbeevers at gmail.com Sun Nov 4 11:28:25 2007 From: duncanbeevers at gmail.com (Duncan Beevers) Date: Sun, 4 Nov 2007 11:28:25 -0500 Subject: [mocha-developer] Returning the mock associated with an expectation. Message-ID: <6a2b4fd00711040828x23fa8193n612285bb51a8de7e@mail.gmail.com> I was reading through the FlexMock docs and noticed the expectation method .mock, which returns the original mock associated with an expectation. It looks really handy for writing nice all-in-one mocks like: mock_user = mock('User').expects(:first_name).returns('Jonah').mock So I started playing around with mocha and found I could actually already do this! But I'm not sure how. There's no attr_reader on @mock, and I couldn't find out where this method is defined. So, perhaps we could add this an explicit method on Expectation and include a little rdoc on it? I think a lot of people would get benefit from making this explicit. Opinions? From jamesmead44 at gmail.com Sun Nov 4 15:19:17 2007 From: jamesmead44 at gmail.com (James Mead) Date: Sun, 4 Nov 2007 20:19:17 +0000 Subject: [mocha-developer] Returning the mock associated with an expectation. In-Reply-To: <6a2b4fd00711040828x23fa8193n612285bb51a8de7e@mail.gmail.com> References: <6a2b4fd00711040828x23fa8193n612285bb51a8de7e@mail.gmail.com> Message-ID: <1db558f00711041219y3adbf323o5324607b53cba6c9@mail.gmail.com> On 04/11/2007, Duncan Beevers wrote: > > I was reading through the FlexMock docs and noticed the expectation > method .mock, which returns the original mock associated with an > expectation. > > It looks really handy for writing nice all-in-one mocks like: > > mock_user = mock('User').expects(:first_name).returns('Jonah').mock > > So I started playing around with mocha and found I could actually > already do this! > But I'm not sure how. There's no attr_reader on @mock, and I couldn't > find out where this method is defined. > > So, perhaps we could add this an explicit method on Expectation and > include a little rdoc on it? > I think a lot of people would get benefit from making this explicit. > > Opinions? > Hmm. I think this may have disappeared in some recent refactoring in trunk. Rather than exposing too much of the internals, I keep meaning to add a syntax like this... mock_user = mock('User') { expects(:first_name).returns('James') stubs(:last_name).returns('Mead') } Would that help you do what you want to do...? Alternatively did you know you could already do... mock_user = mock('User', :first_name => 'James', :last_name => 'Mead') However there are a couple of limitations with this - you can't mix expects & stubs and you can't specify anything other than a returns() e.g. no with(), no raises(), etc. What do you think? -- James. http://blog.floehopper.org http://tumble.floehopper.org From duncanbeevers at gmail.com Mon Nov 5 00:43:42 2007 From: duncanbeevers at gmail.com (Duncan Beevers) Date: Mon, 5 Nov 2007 00:43:42 -0500 Subject: [mocha-developer] Returning the mock associated with an expectation. In-Reply-To: <1db558f00711041219y3adbf323o5324607b53cba6c9@mail.gmail.com> References: <6a2b4fd00711040828x23fa8193n612285bb51a8de7e@mail.gmail.com> <1db558f00711041219y3adbf323o5324607b53cba6c9@mail.gmail.com> Message-ID: <6a2b4fd00711042143o187c3f57sea8ab809af54d7b8@mail.gmail.com> The block syntax looks excellent, and reads very nicely. I especially like the idea of not having to pass in the mock to the block to stick the expectations onto, and instead just continue fluently adding expectations. This block syntax also feels like the right direction to go if there were to be some kind of expectations on the ordering of method calls. I haven't run into a testing situation where I've needed to test the ordering of calls on a mock explicitly, but flex mock provides a grouping mechanism. For the corollary in FlexMock, check out #ordered http://onestepback.org/software/flexmock/classes/FlexMock/Expectation.html#M000082 Don't take me too seriously, but I think mocha could trump flexmock's with something like: mock_user = mock('User') do initially.expects(:first_name).returns('Duncan') then.expects(:last_name).returns('Beevers') later.expects(:birthday).returns('a gentleman never asks') then.expects(:astrological_sign).returns('Virgo') stubs(:favorite_color).returns('silver') finally.expects(:goodnight!).returns('same to you') end Where the temporal prefixes initially, finally, then and later indicate method call ordering, and expectations without a temporal prefix can be called freely. Am I pulling this out of my ass? Yes. On Nov 4, 2007 3:19 PM, James Mead wrote: > > On 04/11/2007, Duncan Beevers wrote: > > > > I was reading through the FlexMock docs and noticed the expectation > > method .mock, which returns the original mock associated with an > > expectation. > > > > It looks really handy for writing nice all-in-one mocks like: > > > > mock_user = mock('User').expects(:first_name).returns('Jonah').mock > > > > So I started playing around with mocha and found I could actually > > already do this! > > But I'm not sure how. There's no attr_reader on @mock, and I couldn't > > find out where this method is defined. > > > > So, perhaps we could add this an explicit method on Expectation and > > include a little rdoc on it? > > I think a lot of people would get benefit from making this explicit. > > > > Opinions? > > > > Hmm. I think this may have disappeared in some recent refactoring in trunk. > Rather than exposing too much of the internals, I keep meaning to add a > syntax like this... > > mock_user = mock('User') { > expects(:first_name).returns('James') > stubs(:last_name).returns('Mead') > } > > Would that help you do what you want to do...? > > Alternatively did you know you could already do... > > mock_user = mock('User', :first_name => 'James', :last_name => 'Mead') > > However there are a couple of limitations with this - you can't mix expects > & stubs and you can't specify anything other than a returns() e.g. no > with(), no raises(), etc. > > > What do you think? > -- > James. > http://blog.floehopper.org > http://tumble.floehopper.org > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer > From jamesmead44 at gmail.com Tue Nov 13 08:18:23 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 13 Nov 2007 13:18:23 +0000 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: References: Message-ID: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> On 13/11/2007, Pradeep Gatram wrote: > > Let me put my dilemma as an example. Take a look at a snippet from > FooTest. > > #using mocha > def test_method1 > Bar.expects(:method2).with('param1', 'param2').once > Foo.method1 > end > > And now the implementation > > class Foo > def self.method1 > Bar.method2('param1', 'param2') > end > end > > class Bar > end > > So far so good... Now my dilemma is that while implementing method2 in > Bar, I can come up with any weird signature (e.g. def method2 > someInteger, someOtherNumber) and I will not be breaking FooTest. This > obviously makes life hard while refactoring. Coming from a Java/C# > background, I used to rely on compilation to catch these issues. > > How have people solved such problems? > > Pradeep Hi Pradeep, Fundamentally you should never rely on only mock based tests, you should always have some functional tests to check all the objects are wired together correctly, but... Mocha [1] used to only allow you to mock *existing* methods on *concrete* classes. This functionality accidentally got removed a while ago, but I'd like to reintroduce it asap. You can already restrict expecations on *mocks* by using the responds_like modifier [2], something like this... class Foo def bar end end def test_me foo = mock('foo') foo.responds_like(Foo.new) foo.expects(:not_bar) foo.not_bar end # => NoMethodError: undefined method `not_bar' for # which responds like # -- James. http://blog.floehopper.org http://tumble.floehopper.org [1] http://mocha.rubyforge.org [2] http://mocha.rubyforge.org/classes/Mocha/Mock.html#M000032 From dchelimsky at gmail.com Tue Nov 13 09:44:19 2007 From: dchelimsky at gmail.com (David Chelimsky) Date: Tue, 13 Nov 2007 08:44:19 -0600 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> References: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> Message-ID: <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> On Nov 13, 2007 7:18 AM, James Mead wrote: > Mocha [1] used to only allow you to mock *existing* methods on *concrete* > classes. This functionality accidentally got removed a while ago, but I'd > like to reintroduce it asap. I beg of you, please don't. At least not as a default behaviour. Mocks are very powerful tools for interface discovery (http://www.jmock.org/oopsla2004.pdf). With an enforcement rule like the one you propose reinstating, we'd have to stop working on the object at hand to go write a class and/or method. This would break the flow of the current task, force us to shift focus. Not only do we break the current flow, but by going over to the other object and sticking in a stub to get the mock to shut up, we run a far greater risk of leaving things 1/2 done than we do by sending unsupported messages and have our integration tests expose those holes. For anybody who is serious about doing TDD, this would be a major step backwards. What we've talked about adding to ... ahem ... another mocking library, is the ability engage this behaviour explicitly with an environment variable or a command line switch. That would provide the best of both worlds because you could stay focused on the task at hand AND you could get a report of the methods you don't have on collaborating classes so you know where to go next. I'd strongly recommend that you consider a similar path before simply forcing this rule on mocha users. Cheers, David From zach.lists at gmail.com Tue Nov 13 09:50:06 2007 From: zach.lists at gmail.com (Zach Moazeni) Date: Tue, 13 Nov 2007 09:50:06 -0500 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> References: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> Message-ID: <57EB1CC5-DB55-4D0B-9EEB-7DEBDC4B2740@gmail.com> +1 on David's response. -Zach On Nov 13, 2007, at 9:44 AM, David Chelimsky wrote: > On Nov 13, 2007 7:18 AM, James Mead wrote: >> Mocha [1] used to only allow you to mock *existing* methods on >> *concrete* >> classes. This functionality accidentally got removed a while ago, >> but I'd >> like to reintroduce it asap. > > I beg of you, please don't. At least not as a default behaviour. > > Mocks are very powerful tools for interface discovery > (http://www.jmock.org/oopsla2004.pdf). With an enforcement rule like > the one you propose reinstating, we'd have to stop working on the > object at hand to go write a class and/or method. This would break the > flow of the current task, force us to shift focus. > > Not only do we break the current flow, but by going over to the other > object and sticking in a stub to get the mock to shut up, we run a far > greater risk of leaving things 1/2 done than we do by sending > unsupported messages and have our integration tests expose those > holes. > > For anybody who is serious about doing TDD, this would be a major step > backwards. > > What we've talked about adding to ... ahem ... another mocking > library, is the ability engage this behaviour explicitly with an > environment variable or a command line switch. That would provide the > best of both worlds because you could stay focused on the task at hand > AND you could get a report of the methods you don't have on > collaborating classes so you know where to go next. > > I'd strongly recommend that you consider a similar path before simply > forcing this rule on mocha users. > > Cheers, > David > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer From jamesmead44 at gmail.com Tue Nov 13 10:54:46 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 13 Nov 2007 15:54:46 +0000 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: <57EB1CC5-DB55-4D0B-9EEB-7DEBDC4B2740@gmail.com> References: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> <57EB1CC5-DB55-4D0B-9EEB-7DEBDC4B2740@gmail.com> Message-ID: <1db558f00711130754g53e8ae0cw50d06b514a0549d4@mail.gmail.com> > > On Nov 13, 2007, at 9:44 AM, David Chelimsky wrote: > > I beg of you, please don't. At least not as a default behaviour. > > > > Mocks are very powerful tools for interface discovery > > (http://www.jmock.org/oopsla2004.pdf). With an enforcement rule like > > the one you propose reinstating, we'd have to stop working on the > > object at hand to go write a class and/or method. This would break the > > flow of the current task, force us to shift focus. > > > > Not only do we break the current flow, but by going over to the other > > object and sticking in a stub to get the mock to shut up, we run a far > > greater risk of leaving things 1/2 done than we do by sending > > unsupported messages and have our integration tests expose those > > holes. > > > > For anybody who is serious about doing TDD, this would be a major step > > backwards. > > > > What we've talked about adding to ... ahem ... another mocking > > library, is the ability engage this behaviour explicitly with an > > environment variable or a command line switch. That would provide the > > best of both worlds because you could stay focused on the task at hand > > AND you could get a report of the methods you don't have on > > collaborating classes so you know where to go next. > > > > I'd strongly recommend that you consider a similar path before simply > > forcing this rule on mocha users. > > > > Cheers, > > David > Don't panic! I wouldn't dream of forcing it on anybody - I was envisaging something similar to what you suggest.-- James. http://blog.floehopper.org http://tumble.floehopper.org From dchelimsky at gmail.com Tue Nov 13 11:51:21 2007 From: dchelimsky at gmail.com (David Chelimsky) Date: Tue, 13 Nov 2007 10:51:21 -0600 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: <1db558f00711130754g53e8ae0cw50d06b514a0549d4@mail.gmail.com> References: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> <57EB1CC5-DB55-4D0B-9EEB-7DEBDC4B2740@gmail.com> <1db558f00711130754g53e8ae0cw50d06b514a0549d4@mail.gmail.com> Message-ID: <57c63afe0711130851j7142d5e4m827f7e8e170ba256@mail.gmail.com> On Nov 13, 2007 9:54 AM, James Mead wrote: > > On Nov 13, 2007, at 9:44 AM, David Chelimsky wrote: > > > What we've talked about adding to ... ahem ... another mocking > > > library, is the ability engage this behaviour explicitly with an > > > environment variable or a command line switch. That would provide the > > > best of both worlds because you could stay focused on the task at hand > > > AND you could get a report of the methods you don't have on > > > collaborating classes so you know where to go next. > Don't panic! I've read that somewhere before :) > I wouldn't dream of forcing it on anybody - I was envisaging > something similar to what you suggest.-- Great. Thanks! Cheers, David From dchelimsky at gmail.com Tue Nov 13 11:51:21 2007 From: dchelimsky at gmail.com (David Chelimsky) Date: Tue, 13 Nov 2007 10:51:21 -0600 Subject: [mocha-developer] how to ensure signature compliance while mocking in ruby In-Reply-To: <1db558f00711130754g53e8ae0cw50d06b514a0549d4@mail.gmail.com> References: <1db558f00711130518y554d2238u9eab30d302808b59@mail.gmail.com> <57c63afe0711130644p1e9c92c4y7350e38159eb35f3@mail.gmail.com> <57EB1CC5-DB55-4D0B-9EEB-7DEBDC4B2740@gmail.com> <1db558f00711130754g53e8ae0cw50d06b514a0549d4@mail.gmail.com> Message-ID: <57c63afe0711130851j7142d5e4m827f7e8e170ba256@mail.gmail.com> On Nov 13, 2007 9:54 AM, James Mead wrote: > > On Nov 13, 2007, at 9:44 AM, David Chelimsky wrote: > > > What we've talked about adding to ... ahem ... another mocking > > > library, is the ability engage this behaviour explicitly with an > > > environment variable or a command line switch. That would provide the > > > best of both worlds because you could stay focused on the task at hand > > > AND you could get a report of the methods you don't have on > > > collaborating classes so you know where to go next. > Don't panic! I've read that somewhere before :) > I wouldn't dream of forcing it on anybody - I was envisaging > something similar to what you suggest.-- Great. Thanks! Cheers, David From jamesmead44 at gmail.com Thu Nov 15 13:05:34 2007 From: jamesmead44 at gmail.com (James Mead) Date: Thu, 15 Nov 2007 18:05:34 +0000 Subject: [mocha-developer] ParameterMatcher backwards compatibility broken Message-ID: <1db558f00711151005i4919c9c9k72b954b79e990fa6@mail.gmail.com> I've just committed (revision 194) a first stab at supporting optional parameter matching. More about this later, but in the meantime I wanted to warn anyone bold enough to be working with "edge" Mocha, that any custom parameter matchers they have written will be broken by this change. However it is easy enough to fix them. You need to derive the matcher from ParameterMatcher::Base and you need to change the "==" method to "matches?". This method is now supplied with an array of the remaining parameters to match and you are expected to "consume" any parameters that you match. It's probably easiest to see in an example [1] which includes both old and new versions. And here [2] is a diff file for the same class. Please let me know if I've broken anything. Thanks. -- James. http://blog.floehopper.org http://tumble.floehopper.org [1] http://pastie.caboo.se/118417 [2] http://pastie.caboo.se/118419