I really like the idea of Mock Proxies as explained in Brian Takita''s
post here:
http://pivots.pivotallabs.com/users/brian/blog/articles/352-introducing-rr
I posted to this list eariler with an incomplete implementation of
.stops_mocking in the thread "Mocking Time, delegating to original
object." The Mock Proxy pattern would make this simpler.
Proxy(User).expects(:find).with(99) # Sets expectation, forwards
method invocation to original class
User.expects(:find).with(99).returns(nil).then.proxies # Canned
response, then forwards successive invocations to original class.
Most of this is just my desire to be lazy and not actually have to
unit-test *trivial* methods explicitly. I also like the idea of using
the Mock Proxy to exercise the behavior of simple private instance
methods of my class which are kind of a pain to test currently, which
leads to my not making anything private.
On Jan 2, 2008 6:50 AM, James Mead <jamesmead44 at gmail.com>
wrote:>
> 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
>
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer
>