Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is mock.patch class decorator not working?

Tags:

python

mocking

I want to mock something for an entire class but the following minimal example is not working:

import time
import six
if six.PY2:
    import mock
else:
    from unittest import mock

@mock.patch('time.sleep', mock.Mock(side_effect=Exception('dooooom')))
class Foo(object):
    def bar(self):
        print('before')
        time.sleep(1)
        print('after')

f = Foo()
f.bar()

I get this unexpected output: (why did time.sleep not raise?)

before
after

However if I move the @mock.patch(...) down 1 line so it is decorating the method bar instead of the class Foo then it works as expected:

before
...
Exception: blah

Why does @mock.patch not work at the class level?

like image 439
sparrowt Avatar asked Oct 29 '25 07:10

sparrowt


1 Answers

It turns out the class decorator only patches methods beginning with patch.TEST_PREFIX which defaults to test.

So renaming the method to test_bar or even testbar makes the patch start working.

Docs:

Patch can be used as a TestCase class decorator. It works by decorating each test method in the class. This reduces the boilerplate code when your test methods share a common patchings set. patch() finds tests by looking for method names that start with patch.TEST_PREFIX. By default this is 'test', which matches the way unittest finds tests. You can specify an alternative prefix by setting patch.TEST_PREFIX.

Evidently this behaviour applies to any class whether inheriting from unittest.TestCase or not.

like image 106
sparrowt Avatar answered Oct 31 '25 12:10

sparrowt