Which mock library do you prefer?

Ben Finney ben+python at benfinney.id.au
Wed Feb 17 20:20:49 EST 2010


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

> Right, isolation [of test cases] is essential. But I can't decide to
> which extent I should propagate isolation.

You used “propagate” in a sense I don't understand there.

> For example, in "Python Testing: Beginner's Guide" by Daniel Arbuckle,
> author suggests that if you do unittesting you should isolate the
> smallest units of code from each other.

I'm not sure what the author means, but I would say that as it stands
that advice is independent of what testing is being done. In all cases:

* Make your code units small, so each one is not doing much and is easy
  to understand.

* Make the interface of units at each level as narrow as feasible, so
  they're not brittle in the face of changes to the implementation.

> For example, if you have a
> class:
> Class SomeClass(object):
>     def method1(self):
>         return 5
>     def method2(self):
>         return self.method1 + 10
>
> According to the book, if you want to test method2, you should isolate
> it from method1 and class instance('self').

I don't really know what that means.

Remember that each test case should not be “test method1”. That is far
too broad, and in some cases too narrow. There is no one-to-one mapping
between methods and unit test cases.

Instead, each test case should test one true-or-false assertion about
the behaviour of the code. “When we start with this initial state (the
test fixture), and perform this operation, the resulting state is that”.

It makes a lot of sense to name the test case so the assertion being
made *is* its name: not ‘test frobnicate’ with dozens of assertions, but
one ‘test_frobnicate_with_valid_spangulator_returns_true’ which makes
that assertion, and extra ones for each distinct assertion.

The failure of a unit test case should indicate *exactly* what has gone
wrong. If you want to make multiple assertions about a code unit, write
multiple test cases for that unit and name the tests accordingly.

This incidentally requires that you test something small enough that
such a true-or-false assertion is meaningful, which leads to
well-designed code with small easily-tested code units. But that's an
emergent property, not a natural law.

> Currently, I don't create mocks of units if they are within the same
> class with the unit under test. If that is not right approach, please,
> explain what are best practices... I am just learning TDD..

In the fixture of the unit test case, create whatever test doubles are
necessary to put your code into the initial state you need for the test
case; then tear all those down whatever the result of the test case.

If you need to create great honking wads of fixtures for any test case,
that is a code smell: your code units are too tightly coupled to
persistent state, and need to be decoupled with narrow interfaces.

The Python ‘unittest’ module makes this easier by letting you define
fixtures common to many test cases (the ‘setUp’ and ‘tearDown’
interface). My rule of thumb is: if I need to make different fixtures
for some set of test cases, I write a new test case class for those
cases.

-- 
 \       “Following fashion and the status quo is easy. Thinking about |
  `\        your users' lives and creating something practical is much |
_o__)                                harder.” —Ryan Singer, 2008-07-09 |
Ben Finney



More information about the Python-list mailing list