Fake It Til You Make It: Unit Testing Patterns With Mocks And Fakes by Brian K. Jones

Presenters: Brian K. Jones

PyCon 2012 presentation page: https://us.pycon.org/2012/schedule/presentation/336/


Video: https://www.youtube.com/watch?v=hvPYuqzTPIk&list=PLBC82890EA0228306&index=13&feature=plpp_video

Video running time: 49:33

Your Speaker


What’s covered


  • Definitions
  • Patterns
  • Tools

What’s not covered


  • Intro to the unittest module
  • Sales pitch for doing testing at all

What is a “unit test”?


  • A test that exercises a very small amount of code which is completely isolated from any and all dependencies, external or internal
  • Granular – only testing a small piece of code
  • Isolated
  • Localized – tells you exactly where your bug is

When it is no longer a unit test?


  • When something else in the larger system, besides the code under test, has to work.

What is it then?


  • If multiple components of the same class or system are tested, and the test seeks to determine that these components interact in a predictable way, it’s an integration test.
  • If the entire system is being tested to insure compliance with a spec of some kind, it’s an acceptance test.

What is “coverage”?


  • A loaded term
  • Often generically referred to as “code coverage”.
  • What you really want is “condition coverage”, “case coverage”, “logic coverage”, “decision-point coverage”, etc.

Use coverage.py



Speaking of nosetests


  • Nose is a great test discovery tool
  • cd to your test directory and run “nosetests”. Rejoice.
  • nosetests --with-coverage (coverage.py is a nose plugin!)
  • Has a super nice HTML report that highlights covered/uncovered lines
  • Integrates well with Jenkins to present html and provide pretty graphs (managers like those):

Why unit tests?


  • They’re fast
  • They’re simple
  • They provide greater localization of problems than other types of tests often can

Unit tests aren’t enough


Unit tests don’t test integration - that the parts of the system all work together

A problem


(Sample Python code from PyRabbit)

A solution


An integration test


(12:26) “Reality distortion field”

Mock is cool. Use it.


  • http://mock.readthedocs.org/en/latest/index.html
  • It patches all the things
  • Often used as a “spy” library (technically)
  • I use it so I don’t have to create my own mocking classes.
  • Action->Assertion > Record->Replay
    • Action->Assertion is closer to how developers tend to think about their code

Mock handles harder stuff






More testable code


Why there is resistance to adopting unit testing

Requires deeper knowledge of code

Requires special techniques

You have to invest time to learn it

A lot of managers, especially with large code bases, will not want to make that investment

However, unit testing will improve the design of your code.

Low-hanging fruit


  • Limit the scope of responsibility
  • Create local wrappers
  • Deduplicate the code

An example


get_path method



Practical patterns Part 1: A datetime abstraction library


Practical patterns Part 2: A REST client module



  • It’s a cient for RabbitMQ’s REST Management API
  • ~250 lines of executable code
  • ~200 lines of unit test code
  • Uses httplib2 to talk to the server
  • Tests pass with Python 2.6, 2.7, and 3.2
  • Use tox

tox is cool



envlist = py26,py27,py32

deps =
changedir = tests
commands = nosetests []

deps =
changedir = tests
commands = nosetests []

Other tricks


Mocking stdout


outstream = StringIO()

with patch('sys.stdout', new=outstream) as out:
    actual_out = out.getvalue()

Testing decorated functions


We’ve covered


  • What’s a unit test? Why are they cool? How can I make some?
  • Are unit tests all I need?
  • What’s Mock ? Why is it cool? How can I use it?
  • Use tox! Use nosetests! Use coverage.py!
  • Testing a simple one-module date manipulation library
  • Testing a REST API client library
  • And more!



  • Mock is going to be in the Python Standard Library in Python 3.3 as unittest.mock.
  • Question: How to organize integration tests?
  • Question: When do you find doctests useful?
  • Question: Design for testability (e.g.: dependency injection) vs. monkey-patching
    • Dependency injection is something that you need a team to be bought into
  • Comment (from Gary Bernhardt). Decorators make testing harder because they couple things together at compile-time. The solution is dependency injection.