Created
December 19, 2012 04:42
-
-
Save ooharak/4334432 to your computer and use it in GitHub Desktop.
A python mock object factory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# written by ooharak 2012. https://github.com/ooharak | |
# Usage: | |
# # an example test target | |
# def target(): | |
# import os | |
# os.putenv('DUMMY', os.getenv('PATH')+'#'+os.getenv('USER')) | |
# | |
# ... | |
# | |
# # setup mock | |
# import oremock | |
# m = oremock.OreMock() | |
# m.to_mock('os.getenv', ['/bin','scott']) | |
# m.to_mock('os.putenv') | |
# | |
# # call the test target | |
# try: | |
# target() | |
# | |
# # check phase | |
# assertEqual(['os.getenv', 'os.getenv', 'os.putenv'], m.callorder) | |
# assertEqual('PATH', m.getcall('os.getenv')[0]) | |
# assertEqual('USER', m.getcall('os.getenv')[0]) | |
# assertEqual(('DUMMY','/bin#scott'), m.getcall('os.putenv')) | |
# # check that no more calls were made | |
# assertFalse(m.hasCalled('os.putenv')) | |
# assertFalse(m.hasCalled('os.getenv')) | |
# finally: | |
# m.unmock_all() | |
# | |
# | |
# | |
# | |
# | |
class OreMock(object): | |
"""tiny mock object factory""" | |
def __init__(self): | |
self.callorder = [] | |
self.calls = {} | |
self.orgs = {} | |
self.objnames = {} | |
self.rets = {} | |
def _mock(self, name, *param, **nparam): | |
import exceptions | |
#import java.lang | |
pdata = param | |
if len(nparam) > 0: | |
pdata = param + (nparam,) | |
self.callorder.append(name) | |
if self.calls.has_key(name): | |
self.calls[name].append(pdata) | |
else: | |
self.calls[name] = [pdata] | |
if self.rets[name] == None: | |
return None | |
else: | |
try: | |
ret = self.rets[name].pop(0) | |
if isinstance(ret, exceptions.Exception): | |
raise ret | |
#elif isinstance(ret, java.lang.Exception): | |
# raise ret | |
else: | |
return ret | |
except IndexError: | |
raise 'No more call of ' + name | |
# shift the parameter by one | |
def getcall(self, name): | |
try: | |
return self.calls[name].pop(0) | |
except KeyError: | |
raise 'Never called: ' + name | |
except IndexError: | |
raise 'No more call of '+name | |
# returns whether this mock has one or more calls recorded but yet not getcall()'d | |
def hasCalled(self, name): | |
return self.calls.has_key(name) and len(self.calls[name]) > 0 | |
# replace a function of the name objname to a mock. | |
# each call to that mock will return an element of the array specified with ret. | |
# name is an alias for the mock. | |
def to_mock_as(self, name, objname, ret=None): | |
self.objnames[name] = objname | |
if '.' in objname: | |
exec('import ' + '.'.join(objname.split('.')[0:-1])) in globals(), locals() | |
exec('orgval = '+objname) in globals(), locals() | |
self.orgs[name] = orgval | |
self.rets[name] = ret | |
m = lambda *p, **pp: self._mock(name, *p, **pp) | |
exec(objname + ' = m') in globals(), locals() | |
def to_mock(self, objname, ret=None): | |
return self.to_mock_as(objname, objname, ret) | |
def unmock_all(self): | |
for i in self.objnames.items(): | |
name = i[0] | |
objname = i[1] | |
if '.' in objname: | |
exec('import ' + '.'.join(objname.split('.')[0:-1])) in globals(), locals() | |
obj = self.orgs[name] | |
exec(objname + ' = obj') in globals(), locals() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment