Replacing module with a stub for unit testing

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat May 23 09:25:05 EDT 2009


On Sat, 23 May 2009 06:00:15 -0700, pigmartian wrote:

> Hi,
> 
> I'm working on a unit test framework for a module.  The module I'm
> testing indirectly calls another module which is expensive to access ---
> CDLLs whose functions access a database.
...
> The examples I can find of creating and using Mock or Stub objects seem
> to all follow a pattern where the fake objects are passed in as
> arguments to the code being tested.  For example, see the "Example
> Usage" section here: http://python-mock.sourceforge.net.  But that
> doesn't work in my case as the module I'm testing doesn't directly use
> the module that I want to replace.
> 
> Can anybody suggest something?

Sounds like a job for monkey-patching!

Currently, you have this:

# inside test_MyModule:
import MyModule
test_code()


# inside MyModule:
import IntermediateModule


# inside IntermediateModule:
import ExpensiveModule


You want to leave MyModule and IntermediateModule as they are, but 
replace ExpensiveModule with MockExpensiveModule. Try this:

# inside test_MyModule:
import MyModule
import MockExpensiveModule
MyModule.IntermediateModule.ExpensiveModule = MockExpensiveModule
test_code()



That should work, unless IntermediateModule uses "from ExpensiveModule 
import functions" instead of "import ExpensiveModule". In that case, you 
will have to monkey-patch each individual object rather than the entire 
module:

MyModule.IntermediateModule.afunc = MockExpensiveModule.afunc
MyModule.IntermediateModule.bfunc = MockExpensiveModule.bfunc
MyModule.IntermediateModule.cfunc = MockExpensiveModule.cfunc
# etc...



-- 
Steven



More information about the Python-list mailing list