4

Given code like this in somemod.py:

try:
    Import cStringIO as StringIO
except ImportError:
    import StringIO

How can one test the 'fallback' branch?

(Use case: trying to achieve 100% coverage. Agreed that this is a bit of a silly goal :) )

Complications:

  1. code runs from test_somemod.py which has import somemod
  2. Mocking ImportError in Python covers some of this, but is complicated!
Community
  • 1
  • 1
Gregg Lind
  • 20,690
  • 15
  • 67
  • 81

1 Answers1

3

First, create a function to use for testing:

>>> def somecode():
...    try:
...       import cStringIO as StringIO
...       print 'got cStringIO'
...    except ImportError:
...       import StringIO
...       print 'got StringIO'
>>> somecode()
got cStringIO

Now, as explained here, you can hook in to the import function:

>>> import __builtin__
>>> original_import = __builtin__.__import__
>>> def import_hook(name, *args, **kwargs):
...    if name == 'cStringIO': raise ImportError('test case module import failure')
...    else: return original_import(name, *args, **kwargs)
... 
>>> 
>>> __builtin__.__import__ = import_hook
>>> somecode()
got StringIO

After the test case, you should set it back:

>>> __builtin__.__import__ = original_import
Wolph
  • 78,177
  • 11
  • 137
  • 148
jterrace
  • 64,866
  • 22
  • 157
  • 202
  • For extra credit, any way to get mock.patch involved to do this only for particular test cases? – Gregg Lind Sep 28 '11 at 22:56
  • Hmm, never used mock.patch, but it should be easy to make this into a decorator where you can give it a list of modules to 'hide' on enter and set back on exit. – jterrace Sep 28 '11 at 23:48
  • 2
    So far, it seems like messing around with import gives some ugliness. My real solution is to use "# pragma: no cover" to make coverage.py ignore it! I will have to dig out my experiements. – Gregg Lind Sep 28 '11 at 23:51