Duncan Beevers
2007-Nov-04 16:28 UTC
[mocha-developer] Returning the mock associated with an expectation.
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?
James Mead
2007-Nov-04 20:19 UTC
[mocha-developer] Returning the mock associated with an expectation.
On 04/11/2007, Duncan Beevers <duncanbeevers at gmail.com> 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
Duncan Beevers
2007-Nov-05 05:43 UTC
[mocha-developer] Returning the mock associated with an expectation.
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 <jamesmead44 at gmail.com> wrote:> > On 04/11/2007, Duncan Beevers <duncanbeevers at gmail.com> 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 >
James Mead
2008-Jan-02 14:50 UTC
[mocha-developer] Returning the mock associated with an expectation.
On 05/11/2007, Duncan Beevers <duncanbeevers at gmail.com> wrote:> 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 <jamesmead44 at gmail.com> wrote: > > > > On 04/11/2007, Duncan Beevers <duncanbeevers at gmail.com> 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 > > > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer >Sorry for taking ages to respond to this. I just wanted to let you know that since revision 193 (which is included in gem 0.5.6), the initializer block syntax has been available. Unfortunately the rdoc didn''t get updated until revision 221 (which hasn''t yet been released). Since your email, I''ve added support for JMock2 style sequences [1] and states [2] which allow you to constrain the order of invocation. I haven''t yet sorted out the error reporting and there may be some teething problems, but feel free to give it a try. All the rdoc has been updated in trunk. See AutoVerify#sequence and AutoVerify#states for details. In the meantime - thanks for you interest and your suggestions. -- James. http://blog.floehopper.org http://tumble.floehopper.org [1] http://jmock.org/sequences.html [2] http://jmock.org/states.html