Check Out Mox, Our Mock Object Framework for Python

Wednesday, July 16, 2008

So you just finished writing a really sweet Python application, and now it's time to do some testing. Or wait, better yet, you're going to write the tests first, then write your application code. It's probably time to pick a mock object framework to make writing tests easy; you definitely don't want to waste your time writing mocks by hand! Well, after many requests from former interns and Googlers working on Open Source projects, I'm happy to announce that now you have another option: Mox!

Mox is a mock object framework for Python developed at Google (and used in hundreds of projects here) that uses the record-replay-verify paradigm you might already be familiar with from library's such as Java's EasyMock. You create a mock object based on a class, record the expected behavior by calling methods on the mock just like a regular instance, then you put the mock in replay mode and run your test. After your test is complete, you can verify that the code-under-test interacted with the mock as expected.

Why would you want / need a mock object framework? In many cases you want to be able to test portions of your code without setting up all of your applications dependencies (databases, file systems, or even just other complex parts of your application). Mox allows you to easily create mock versions of your dependencies (Python classes, even modules) for use in tests. These mock versions only need to know about how they are called (which methods with what parameters), and what they should return. For example, instead of starting up a local copy of MySQL and populating the database with test data just to test that your InsertCustomer method works (or fails elegantly), now you can use Mox to simulate calls to, and responses from the database.

m = mox.Mox()
mock_db = m.CreateMock(database)
new_pk = 12356;
mock_db.Execute("INSERT INTO Customers (fname, lname, email) VALUES
('Sandy', 'Smith', ''").AndReturn(new_pk)

p = PersistenceLogic(mock_db)
actual_pk = p.InsertCustomer('Sandy', 'Smith', '')

assertEquals(new_pk, actual_pk)

Mox has several other advanced features, like the ability to temporarily stub out any object or module with a mock object — even parts of the global environment.

We always love to hear what you think. Please join the Mox discussion group and share your thoughts with us.