Michael Foord is a Python developer and the author of IronPython in Action. Michael has a particular interest in Python testing tools and is the maintainer of the unittest package in the Python standard library. Michael is a DZone MVB and is not an employee of DZone and has posted 10 posts at DZone. You can read more from them at their website. View Full User Profile

unittest.mock and mock 1.0 alpha 1

03.29.2012
| 1780 views |
  • submit to reddit
One of the results of the Python Language Summit at PyCon 2012 is that mock is now in the Python standard library. In Python 3.3 mock is available as unittest.mock.

For those of you who may not know, mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects.

The standard distribution of mock that you all know and love will still be available as a backport of the standard library version, but the standard library is now where new mock development will take place. Inevitably this means development will slow down, with new feature releases following the Python release cycle. As the api has stabilised with the 0.8 release this is a good thing...

However, there were some changes I wanted to make (removing obsolete code and adding a few minor features) before moving into the standard library. This is now complete, and there is a shiny new 1.0 alpha 1 release that matches the version in the Python standard library.

You can install mock 1.0 alpha 1 with:

pip install -U mock==dev easy_install mock


Changes since 0.8
are:

  • mocksignature, along with the mocksignature argument to patch, removed
  • Support for deleting attributes (accessing deleted attributes will raise an AttributeError)
  • Added the mock_open helper function for mocking the builtin open

  • __class__ is assignable, so a mock can pass an isinstance check without requiring a spec
  • Addition of PropertyMock, for mocking properties
  • MagicMocks made unorderable by default (in Python 3). The comparison methods (other than equality and inequality) now return NotImplemented

  • Propagate traceback info to support subclassing of _patch by other libraries
  • BUGFIX: passing multiple spec arguments to patchers (spec , spec_set and autospec) had unpredictable results, now it is an error
  • BUGFIX: using spec=True and create=True as arguments to patchers could result in using DEFAULT as the spec. Now it is an error instead
  • BUGFIX: using spec or autospec arguments to patchers, along with spec_set=True did not work correctly
  • BUGFIX: using an object that evaluates to False as a spec could be ignored
  • BUGFIX: a list as the spec argument to a patcher would always result in a non-callable mock. Now if __call__ is in the spec the mock is callable


Documentation for 1.0a1 can be found at mock.readthedocs.org.

This includes one backwards incompatible change - the removal of mocksignature in all its guises. Normally I would only remove features with a deprecation period, but I wanted it gone before moving mock in the standard library. mocksignature is completely replaced by the create_autospec function and the autospec argument to patch.

There are a whole series of bugfixes around the spec arguments to the patchers. I discovered these whilst taking a look at improving a couple of error messages. That was a rabbit hole that absorbed an entire Sunday afternoon!

There are still two issues I'd like to fix for Python 3.3, but no guarantees:

Published at DZone with permission of Michael Foord, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags: