Programmatically replacing an API for another module

stephen04 at tiscali.co.uk stephen04 at tiscali.co.uk
Tue Nov 21 00:28:12 CET 2006


Tom i think i know what you are talking about. If i do then i have recently 
had to deal with something similar.

One approach could be to create a module that acts as an interface between 
your code and the api whos functions you wish to use.

The interface would consist of wrapper functions for all of the functions 
you wish to use. This interface will only include the wrappers for the api 
functions you will actually use.

Now you have created the interface you will need to import the module whose 
functions you want to wrap up in the interface.

At this point you can either import a stub or the real thing. The code 
snippet would look like this

try:
     import stub_api as api
except:
     import real_api as api

def get():
     return api.get()

.....................etc


So when you are testing you make sure that the stub_api module is available 
to the interface, the try will succeed and you will call stub functions. If 
you do not make the stub_api available then the try will fail, the exception 
will be handled by importing the real_api. In either case functions will be 
callable by using the api. as you have effectively renamed what is being 
imported to api.

The advantages of this are that you only make visible to your code the 
fuctions of the api that you are going to use. And you are isolating changes 
to code to the interface only.

Ok hope this helps.

Steve





"Tom Plunket" <tomas at fancy.org> wrote in message 
news:agb4m25v0o0silbl788qc6jqvk2kran4lv at 4ax.com...
> 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! 





More information about the Python-list mailing list