April 28, 2008
Duck Typing for Mock Objects
In computer programming, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows:
"If it walks like a duck and quacks like a duck, I would call it a duck."
Coming from a strong background in C#, it took awhile for this feature of Python to seem useful. I was use to creating interfaces and creating a proper inheritance chain implementing these interfaces and/or defining abstract base classes, all to have a good set of mock objects to use in unit tests.
I really love the ability to quickly whip out a duck typed class in Python to make simple mock objects so that I am testing my code in a unit test and not boundary objects (e.g. urllib). I don't need to test whether my request is properly handled by the server at the urllib endpoint and that the response is properly read and processed. I need to instead make sure that my request conforms to a published specification and that the expected result/response from the server is processed properly. This also allows my tests to run offline.
Here is an example of some mock objects that I use in pyphanfare:
# pyphanfare/tests/mocks.py from pyphanfare.tests.testdata import data class URLopener: def open(self, url): params = url.split('?').split('&') for param in params: tokens = param.split('=') if tokens.strip() == 'method': return URLhandle(tokens.strip()) def addheader(self, *args): self.headers = args class URLhandle: def __init__(self, method): self.method = method def read(self): return data[self.method]
pyphanfare.tests.testdata is just a Python module that contains test data in
the form of a dictionary object indexed by method name that I am calling on
the API having a value of XML that is expected in the response.