[TIP] Problem mocking a decorator

vanderson.mota at gmail.com vanderson.mota at gmail.com
Tue Dec 28 08:03:04 PST 2010


You should patch the decorator in the module that he is used.

So, instead of using:
@patch("a.catch_bad_args", do_nothing_decorator)

use:
@patch("b.catch_bad_args", do_nothing_decorator)

You should patch functions in the modules where they are used, not
where they were declared. It seems that when you make an import, the
function object is 'copied' into the importer namespace. I hope
someone could give a better explanation than i.

cheers




2010/12/28 Yoni Tsafir <yonix85 at gmail.com>:
> Hi guys,
> I'm pretty new to the world of testing in python, and there's a problem I
> ran into while trying to mock a decorator in the code I'm testing.
> Tell me what am I doing wrong or if this is a missing feature in the mock
> library.
> I have the following code:
> a.py:
> -------
> import sys
> class BadArgsError(Exception):
>     pass
>
> def catch_bad_args(func):
>     def call(*args, **kwargs):
>         try:
>             return func(*args, **kwargs)
>         except BadArgsError, e:
>             print >> sys.stderr, e.args[0]
>             print
>             sys.exit(1)
>     call.__name__ = func.__name__
>     call.__dict__ = func.__dict__
>     call.__doc__  = func.__doc__
>     return call
> b.py
> ------
> from a import BadArgsError, catch_bad_args
> @catch_bad_args
> def foo(arg):
>     if arg > 2:
>         raise BadArgsError("arg is bigger than 2")
>     print "arg is ok"
> test_b.py
> -------------
> import unittest
> from b import foo
> from a import BadArgsError
> from mock import patch
>
> def do_nothing_decorator(func):
>     return func
>
>
> class BTest(unittest.TestCase):
>         @patch("a.catch_bad_args", do_nothing_decorator)
>         def test_three_raises(self):
>                 self.assertRaises(BadArgsError, foo, 3)
>
> Now running the tests:
> -------------------------------
> # python test_b.py
> arg is bigger than 2
> E
> ======================================================================
> ERROR: test_three_raises (__main__.BTest)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "test_b.py", line 13, in test_three_raises
>     self.assertRaises(BadArgsError, foo, 3)
>   File "/usr/lib/python2.6/unittest.py", line 336, in failUnlessRaises
>     callableObj(*args, **kwargs)
>   File "/tmp/a.py", line 14, in call
>     sys.exit(1)
> SystemExit: 1
> ----------------------------------------------------------------------
> Ran 1 test in 0.014s
> FAILED (errors=1)
>
> What am I doing wrong? I tried to change the patch to "b.catch_bad_args" and
> I get the same results, I also tried @patch.object and other combinations...
> No help
>
> Thanks a lot!
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
>
>



-- 
Vanderson Mota dos Santos



More information about the testing-in-python mailing list