[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Which mock library do you prefer?

Lacrima

2/15/2010 4:15:00 PM

Hello!

I am newbie mastering test driven development. I can't clarify myself
which mock library to use.
There are number of them and which one do you prefer?

Two libraries that attracted my attention are:
* minimock
* dingus
As for me the latest one, dingus, is the easiest (see this screencast:
http://vimeo.c... ), but it has very few downloads from pypi,
so it scares me a little.
Minimock has wider usage and community, but I have some troubles using
it. Maybe I am wrong, but with minimock you always have to keep track
the order of imports in your test modules. Well, may be I just don't
understand fully how minimock works.

What are your suggestions?
20 Answers

Phlip

2/15/2010 4:58:00 PM

0

Lacrima wrote:

> I am newbie mastering test driven development. I can't clarify myself
> which mock library to use.
> There are number of them and which one do you prefer?
>
> Two libraries that attracted my attention are:
> * minimock
> * dingus
> As for me the latest one, dingus, is the easiest (see this screencast:http://vimeo.com/394... ), but it has very few downloads from pypi,
> so it scares me a little.
> Minimock has wider usage and community, but I have some troubles using
> it. Maybe I am wrong, but with minimock you always have to keep track
> the order of imports in your test modules. Well, may be I just don't
> understand fully how minimock works.
>
> What are your suggestions?

I have used http://pypi.python.org/pypi/... . It mocks, and it
has a mode that works one method at a time, and another mode that
mocks a method before its owning object gets constructed.

However, TDD is not about mocking, and on greenfield code you should
only mock to recover from some external problem, such as:

- a random number generator
- the system clock
- anything over "the wire" - over a TCP/IP socket
- hardware, such as your graphics or sound

Never mock to avoid hitting the database. Some TDD verbiage advises
"never hit the database". That is a mind-game to force you to decouple
your code. Your objects should always have the option (via
"construction encapsulation") to run as stubs, with some of their
behaviors turned off. And if you TDD low-level code that hits a
database, a mock would only tell the test what it wants to hear. And
if you TDD high-level code that manages business rules, database
records make perfectly good behavioral "fixtures" to support those
rules.

--
Phlip
http://c2.com/cgi/wik...

Steve Howell

2/15/2010 5:03:00 PM

0

On Feb 15, 8:15 am, Lacrima <lacrima.ma...@gmail.com> wrote:
> Hello!
>
> I am newbie mastering test driven development. I can't clarify myself
> which mock library to use.
> There are number of them and which one do you prefer?
>
> Two libraries that attracted my attention are:
> * minimock
> * dingus
> As for me the latest one, dingus, is the easiest (see this screencast:http://vimeo.com/394... ), but it has very few downloads from pypi,
> so it scares me a little.

I've used dingus with success. I wouldn't let the lack of downloads
be a concern; the funny name is probably scaring some people away, and
of course there are other alternatives too.

Lacrima

2/15/2010 6:34:00 PM

0

On Feb 15, 6:57 pm, Phlip <phlip2...@gmail.com> wrote:
> Lacrima wrote:
> > I am newbie mastering test driven development. I can't clarify myself
> > which mock library to use.
> > There are number of them and which one do you prefer?
>
> > Two libraries that attracted my attention are:
> > * minimock
> > * dingus
> > As for me the latest one, dingus, is the easiest (see this screencast:http://vimeo.c... ), but it has very few downloads from pypi,
> > so it scares me a little.
> > Minimock has wider usage and community, but I have some troubles using
> > it. Maybe I am wrong, but with minimock you always have to keep track
> > the order of imports in your test modules. Well, may be I just don't
> > understand fully how minimock works.
>
> > What are your suggestions?
>
> I have usedhttp://pypi.python.org/pypi/.... It mocks, and it
> has a mode that works one method at a time, and another mode that
> mocks a method before its owning object gets constructed.
>
> However, TDD is not about mocking, and on greenfield code you should
> only mock to recover from some external problem, such as:
>
> - a random number generator
> - the system clock
> - anything over "the wire" - over a TCP/IP socket
> - hardware, such as your graphics or sound
>
> Never mock to avoid hitting the database. Some TDD verbiage advises
> "never hit the database". That is a mind-game to force you to decouple
> your code. Your objects should always have the option (via
> "construction encapsulation") to run as stubs, with some of their
> behaviors turned off. And if you TDD low-level code that hits a
> database, a mock would only tell the test what it wants to hear. And
> if you TDD high-level code that manages business rules, database
> records make perfectly good behavioral "fixtures" to support those
> rules.
>
> --
> Phlip
> http://c2.com/cgi/wik...

Hi, Phlip!

Thanks for your reply! Isn't what you are talking about integration
tests? And unit tests should be fully isolated? So even for method
'some_method()' of class A I should mock instance of class A (i.e. to
mock 'self') to test 'some_method()'.

Please, could you explain in more detail your thoughts:
> Your objects should always have the option (via
> "construction encapsulation") to run as stubs, with some of their
> behaviors turned off. And if you TDD low-level code that hits a
> database, a mock would only tell the test what it wants to hear. And
> if you TDD high-level code that manages business rules, database
> records make perfectly good behavioral "fixtures" to support those
> rules.

And could you give an example.
For me it's really hard to develop test first. Often I don't know what
tests to write to replace hardcoded return values by objects that
perform actual work.
I have read several books on TDD and explored http://c2.com/cgi/wiki?TestDrivenD...
and related wikis, but often it seems I don't have enough
understanding to write even simple application.
And sorry for my English.

with regards,
Max.

Phlip

2/15/2010 7:57:00 PM

0

Lacrima wrote:

> Thanks for your reply! Isn't what you are talking about integration
> tests? And unit tests should be fully isolated? So even for method
> 'some_method()' of class A I should mock instance of class A (i.e. to
> mock 'self') to test 'some_method()'.

"Unit test" is a high-end QA concept. Developers can get the best
return on "developer tests". They don't bother with aerospace-quality
isolation between units.

If a TDD test needs to pull in a bunch of modules to pass, that's
generally a good thing, because they all get indirect testing. If they
catch a bug, their local tests might not catch it, but the higher
level tests still have a chance.

(And if your product still needs unit tests, TDD will make them very
easy for a formal QA team to add.)

However, expensive setup is a design smell. That means if a test case
requires too many lines of code for its Assemble phase (before its
Activate and Assert phases), then maybe those lines of code support
objects that are too coupled, and they need a better design.

Throwing mocks at these objects, instead of decoupling them, will
"perfume" the design smell, instead of curing it.

> > "construction encapsulation")

> And could you give an example.

def test_frob(self):
frob = Frob()
frob.knob = Mock()
frob.knob.value = Mock(return_value = 42)
assert 42 == frob.method_using_knob()

We need the mock because we can't control how Frob's constructor built
its knob. So instead, give Frob the option to construct with a Knob:

def test_frob(self):
knob = Knob(42)
frob = Frob(knob)
assert frob.method_using_knob()

Note that in production the Knob constructor never takes a Knob. Maybe
we should upgrade the production code too (!), or maybe Knob's
constructor should only create a knob if it didn't get passed one.
Either technique is acceptable, because the resulting code decouples
Frobs and Knobs just a little bit more.

> For me it's really hard to develop test first. Often I don't know what
> tests to write to replace hardcoded return values by objects that
> perform actual work.

You have read too many books on TDD. C-:

Alternate between writing lines of test and lines of code. Run the
tests after the fewest possible edits, and always correctly predict if
the tests will pass, or will fail, and with what diagnostic. (And
configure your editor to run the stankin tests, no matter how hard it
fights you!) The high-end tricks will get easier after you get the
basic cycle down.

--
Phlip
http://c2.com/cgi/wik...

Ben Finney

2/16/2010 12:17:00 AM

0

Lacrima <lacrima.maxim@gmail.com> writes:

> Minimock has wider usage and community, but I have some troubles using
> it. Maybe I am wrong, but with minimock you always have to keep track
> the order of imports in your test modules. Well, may be I just don't
> understand fully how minimock works.

I'm not sure why you think you need to keep track of the order of
imports.

Simply set up the mocks as you want them, in your fixtures; then, when
tearing down your fixtures, use â??minimock.restore()â?? to restore the
affected namespaces to their initial state.

--
\ â??â?¦ one of the main causes of the fall of the Roman Empire was |
`\ that, lacking zero, they had no way to indicate successful |
_o__) termination of their C programs.â? â??Robert Firth |
Ben Finney

Lacrima

2/16/2010 4:54:00 PM

0

On Feb 16, 2:17 am, Ben Finney <ben+pyt...@benfinney.id.au> wrote:
> Lacrima <lacrima.ma...@gmail.com> writes:
> > Minimock has wider usage and community, but I have some troubles using
> > it. Maybe I am wrong, but with minimock you always have to keep track
> > the order of imports in your test modules. Well, may be I just don't
> > understand fully how minimock works.
>
> I'm not sure why you think you need to keep track of the order of
> imports.
>
> Simply set up the mocks as you want them, in your fixtures; then, when
> tearing down your fixtures, use ‘minimock.restore()’ to restore the
> affected namespaces to their initial state.
>
> --
>  \       “… one of the main causes of the fall of the Roman Empire was |
>   `\        that, lacking zero, they had no way to indicate successful |
> _o__)                  termination of their C programs.” —Robert Firth |
> Ben Finney

Hi Ben!

See these two topics:
http://groups.google.com/group/minimock-dev/browse_thread/thread/bcbb3b...
http://groups.google.com/group/minimock-dev/browse_thread/thread/c41cd9...

There are special cases, which you have to be aware of, if you use
minimock.

Lacrima

2/16/2010 5:08:00 PM

0

On Feb 15, 9:56 pm, Phlip <phlip2...@gmail.com> wrote:
> Lacrima wrote:
> > Thanks for your reply! Isn't what you are talking about integration
> > tests? And unit tests should be fully isolated? So even for method
> > 'some_method()' of class A I should mock instance of class A (i.e. to
> > mock 'self') to test 'some_method()'.
>
> "Unit test" is a high-end QA concept. Developers can get the best
> return on "developer tests". They don't bother with aerospace-quality
> isolation between units.
>
> If a TDD test needs to pull in a bunch of modules to pass, that's
> generally a good thing, because they all get indirect testing. If they
> catch a bug, their local tests might not catch it, but the higher
> level tests still have a chance.
>
> (And if your product still needs unit tests, TDD will make them very
> easy for a formal QA team to add.)
>
> However, expensive setup is a design smell. That means if a test case
> requires too many lines of code for its Assemble phase (before its
> Activate and Assert phases), then maybe those lines of code support
> objects that are too coupled, and they need a better design.
>
> Throwing mocks at these objects, instead of decoupling them, will
> "perfume" the design smell, instead of curing it.
>
> > > "construction encapsulation")
> > And could you give an example.
>
>   def test_frob(self):
>       frob = Frob()
>       frob.knob = Mock()
>       frob.knob.value = Mock(return_value = 42)
>       assert 42 == frob.method_using_knob()
>
> We need the mock because we can't control how Frob's constructor built
> its knob. So instead, give Frob the option to construct with a Knob:
>
>   def test_frob(self):
>       knob = Knob(42)
>       frob = Frob(knob)
>       assert frob.method_using_knob()
>
> Note that in production the Knob constructor never takes a Knob. Maybe
> we should upgrade the production code too (!), or maybe Knob's
> constructor should only create a knob if it didn't get passed one.
> Either technique is acceptable, because the resulting code decouples
> Frobs and Knobs just a little bit more.
>
> > For me it's really hard to develop test first. Often I don't know what
> > tests to write to replace hardcoded return values by objects that
> > perform actual work.
>
> You have read too many books on TDD. C-:
>
> Alternate between writing lines of test and lines of code. Run the
> tests after the fewest possible edits, and always correctly predict if
> the tests will pass, or will fail, and with what diagnostic. (And
> configure your editor to run the stankin tests, no matter how hard it
> fights you!) The high-end tricks will get easier after you get the
> basic cycle down.
>
> --
>   Phlip
>  http://c2.com/cgi/wik...

Hi Phlip!

Thanks for your exhaustive answer.
Actually, I'll investigate your example with 'frob'. From just reading
the example it's not clear for me what I will benefit, using this
approach.
And I have already refused to write totally isolated tests, because it
looks like a great waste of time.

Phlip

2/16/2010 5:38:00 PM

0

On Feb 16, 9:08 am, Lacrima <lacrima.ma...@gmail.com> wrote:

> Thanks for your exhaustive answer.
> Actually, I'll investigate your example with 'frob'. From just reading
> the example it's not clear for me what I will benefit, using this
> approach.

I can't get a good hit for "construction encapsulation" in Google.
(Although I got some good bad ones!)

This paper _almost_ gets the idea:
http://www.netobjectives.com/download/Code%20Qualities%20and%20Pra...

> And I have already refused to write totally isolated tests, because it
> looks like a great waste of time.

Do you run your tests after the fewest possible edits? Such as 1-3
lines of code?

I'm not sure why the TDD books don't hammer that point down...

--
Phlip
http://c2.com/cgi/wik...

Ben Finney

2/16/2010 8:31:00 PM

0

Lacrima <lacrima.maxim@gmail.com> writes:

> And I have already refused to write totally isolated tests, because it
> looks like a great waste of time.

It only looks like that until you chase your tail in a long, fruitless
debugging session because (you later realise) the behaviour of one test
is being affected by another. Test isolation is essential to ensure that
your tests are doing what you think they're doing.

--
\ â??A â??Noâ?? uttered from deepest conviction is better and greater |
`\ than a â??Yesâ?? merely uttered to please, or what is worse, to |
_o__) avoid trouble.â? â??Mohandas K. Gandhi |
Ben Finney

Phlip

2/16/2010 10:50:00 PM

0

On Feb 16, 12:30 pm, Ben Finney <ben+pyt...@benfinney.id.au> wrote:
> Lacrima <lacrima.ma...@gmail.com> writes:

> > And I have already refused to write totally isolated tests, because it
> > looks like a great waste of time.
>
> It only looks like that until you chase your tail in a long, fruitless
> debugging session because (you later realise) the behaviour of one test
> is being affected by another. Test isolation is essential to ensure that
> your tests are doing what you think they're doing.

That is runtime test isolation. It's not the same thing as "unit test
isolation". Just take care in your tearDown() to scrub your
environment.

Google "Mock abuse" from here...

--
Phlip