[TIP] Problem mocking a decorator

Michael Foord fuzzyman at voidspace.org.uk
Tue Dec 28 08:05:44 PST 2010


On 28/12/2010 16:03, vanderson.mota at gmail.com wrote:
> 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.

This is true - you patch modules where they are used rather than where 
they are declared - but I don't think it will help in this case. The 
decorator is *used* when the module is first imported, and patching it 
after it is used will have no effect.

All the best,

Michael Foord

> 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
>>
>>
>
>


-- 
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




More information about the testing-in-python mailing list