Additions and Updates to mock

I've made some additions to the mock module I posted. It now provides some helpers for doing class and module level monkey patching, plus some other minor improvements. The distribution now includes its own unit tests which are useful examples.

I will maintain this module, but I don't intend to grow it a great deal. The point is that it isn't a mocking framework, but makes it easy to implement what are (in my experience) common testing patterns. I am using it with unittest.

Creating a Mock from a Spec

One of the points of unit testing is that you decouple tests of your units from other parts of your code, this is where you use mocks. The problem is that your tests then become coupled to your mocks instead of your production code.

If you provide a mock of a particular API, and you then refactor that API, your code is broken - but your tests will still pass because your mocks still provide the old API.

Mock now provides one solution to this, with the optional spec keyword in the constructor. This creates a mock, using another object (class or instance) as a spec. Only methods / attributes available on the specification object will be available on the mock. You can create a mock from a class without instantiating the class. If the class then changes, but your code or test uses the old API then the test will immediately fail with an AttributeError.

Creating Sentinel Objects

Sometimes when testing you need to test that a specific object is passed as an argument to another method, or returned. It can be common to create named sentinel objects to test this. sentinel provides a convenient way of creating and testing the identity of objects like this.

In this example we monkey patch method to return sentinel.ReturnValue. We want to test that this is the value returned when we call something.

frommockimportMock,sentinel

real=ProductionClass()

real.method=Mock()real.method.return_value=sentinel.ReturnValue

returned=real.something()self.assertEquals(returned,sentinel.ReturnValue,"something returned the wrong value")

Patch Decorators

A common need in tests is to patch a class attribute or a module attribute, for example patching a builtin or patching a class in a module to test that it is instantiated. Modules and classes are effectively global, so patching on them has to be undone after the test or the patch will persist into other tests and cause hard to diagnose problems.

The decorator is applied to a function (called test above). The patching only applies inside the body of the function. You have to call the function explicitly, this can be useful as the test function can take arguments and be used to implement several tests, it can also return values.

Mocking, Patching, Stubbing: all that Stuff

I've been off home ill today, but I have wireless and a laptop...

I've been thinking about mocking, patching, stubbing and all that stuff.

We don't use a mocking library at Resolver, mainly because most of the libraries out there use the 'record -> replay' pattern for testing. The general consensus at Resolver is that 'action -> assertion' [1] is a more readable and intuitive pattern for testing.

As a result I've written an article on the subject, and a simple Mock class that implements the patterns we use most commonly through our test framework:

This is mainly me scratching my own itch, but I hope this will serve as a useful example for those wanting to roll their own mocks.

The one major thing it doesn't do is handle patching at a module /
class level or patching out builtins (just another example of module level
patching). Modules and classes are effectively globals - so any patching
has to be undone which can make for annoying code to write.

I'm also not yet distributing the tests for mock.py - it currently uses
some utilities from the Resolver test framework and I need permission to
distribute these. Along with these are some decorators we use to
simplify class / module patching which hopefully I will also be allowed
to include.

Mock is really a very simple class (< 50 LOC), intended for use with unittest or
similar test frameworks. This is an advantage, over-mocking is a sign
that you have too many dependencies in your code.

Well, 'setup -> action -> assertion' usually. I think this is pretty distinct from setting expectations, which merges the setup and the assertions before the action. Obviously this is a matter of opinion and taste [2].

I've also been working on my presentation for Developer Day, this is a .NET community (yes there is such a thing) event in Reading on Saturday. The talk is 'Dynamic Languages on .NET' and it is based on the talk I gave at Mix UK earlier this year. At Mix I was asked to talk on IronPython and Silverlight, but the feedback I got was that the audience really wanted to know why they should be interested in dynamic languages at all. This talk will include a bit about Silverlight, but will be much more focused on what dynamic languages are and why they are exciting. It will also go over the .NET integration aspects of course.