[TIP] Patching __import__

Michael Foord michael at voidspace.org.uk
Tue May 24 16:06:40 PDT 2011


On 24/05/2011 08:31, Yoni Tsafir wrote:
> Moving a discussion with Michael Foord to TIP so everyone can contribute:
>
> I suggested a feature to the mock framework in which you can mock non 
> existing imports (useful when you are unit-testing platform dependent 
> code).
>
> My solution for this was the following:
>
> real_import = __import__
>
> def windows_safe_import(name, globals={}, locals={}, fromlist=(), 
> *args, **kargs):
>     if name in ["wmi", "win32api"] or (name == "ctypes" and fromlist 
> is not None and "windll" in fromlist):
>         return MagicMock()
>     else:
>         return real_import(name, globals, locals, fromlist, *args, 
> **kargs)
>
> @patch("__builtin__.__import__", new = windows_safe_import)
> class MyTestCase(unittest.TestCase):
> ...
> # (tested module was imported only inside the test so the problematic 
> imports it uses won't be imported before we mock the __import__)
>
> Michael suggested 2 alternatives:
> 1.
>     import sys
>     sys.modules['wmi'] = MagicMock()
>
> 2.
>     @patch.dict('sys.modules', {'wmi': MagicMock()})
>
> Then "import wmi" will find your mock. I'm very wary of 
> overriding __import__ even in tests.
>
> Well, just wanted to update that #1 works well, but #2 causes 
> something weird:
> On PyDev I can run the tests fine, but when I try running them with 
> nosetests, nose doesn't recognize any tests. If I comment out the 
> @patch.dict line, everything works fine.
> Tried to debug it a bit but no luck...

Note that one fix *may* be (if you're using Python 2.5 or more recent) 
to use patch.dict as a context manager so that it is called inside the 
test instead of at test import time:

     def test_something():
         with patch.dict('sys.modules', {'wmi': MagicMock()}):
             ...

All the best,

Michael

> Any ideas?
>
>
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python


-- 
http://www.voidspace.org.uk/

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20110525/9a3fd936/attachment.htm>


More information about the testing-in-python mailing list