Programmatically replacing an API for another module

Larry Bates larry.bates at websafe.com
Mon Nov 20 18:35:36 EST 2006


Tom Plunket wrote:
> I've got a bunch of code that runs under a bunch of unit tests.  It'd
> be really handy if when testing I could supply replacement
> functionality to verify that the right things get called without those
> things actually getting called, since frequently those calls take a
> long time to execute and do things that, well, I don't really want to
> do.
> 
> E.g. imagine you've got a routine which takes a filespec, generates a
> list of files, and copies those files from one location to another. (I
> realize that this example could be multiple functions that should be
> tested independently, but please bear with me.)  You don't actually
> want to do the file copy, but you want to make sure that the file copy
> API is appropriately called.
> 
> Using win32com, I might then use win32file.CopyFile, but from testing
> code I'd like to replace that with a different call, a test function
> that I supply.  Ideally I could replace the whole module, after
> importing the module under test, I could do something like 'win32com =
> __dict__', and assuming I had a CopyFile function defined in the test
> module, it'd hook right in.  However, I'm suspicious that this
> wouldn't actually override the win32com seen by the other module that
> will actually do the execution (and I don't yet understand Python's
> execution model sufficiently).
> 
> At present, ModuleTest.py does 'from Module import *' and then makes
> calls on Module without the "Module." decoration.  Since typically a
> file named SomeClass.py will only define the SomeClass class, this is
> more of a convenience than anything.  If this is a barrier to
> replacing APIs, though, well, I can change it.
> 
> Any insight is helpful, thanks.
> 
> 
> -tom!

Whatever points to something in Python is what is called.

example

def abc(a, b):
    z=a+b
    return z

def efg(a, b):
    z=a*b
    return z


f=abc
print f(1,2)
f=efg
print f(1,2)

As long as you implement the full API, you can replace functions
with others quite easily.  Note: this also works with class methods.

Observation: IMHO it is going to be really hard to keep your functional
shims up to date as you change your REAL functions/methods.  You also
are testing different code than you are executing which doesn't make
the unit tests nearly as valuable.

-Larry



More information about the Python-list mailing list