Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override the class patch with method patch (decorator)

I have several test methods in a class that use one type of patching for a object, so I have patched with class decorator. For a single another method i want to patch the same object differently. I tried the following approach, but the patch made as class decorator is in effect despite the method itself being decorated with different patch. I expected method patch to override class patch. Why is this not the case?

In this particular case I can remove class patch and patch individual methods, but that would be repetitive. How can I implement such overriding (method overrides class patch) mechanism?

from unittest TestCase
from unittest import mock

@mock.patch('my_module.cls.method', mock.Mock(side_effect=RuntimeError('testing'))
class SwitchViewTest(TestCase):

    def test_use_class_patching(self):
        # several other methods like this
        # test code ..

    @mock.patch('my_module.cls.method', mock.Mock(side_effect=RuntimeError('custom'))
    def test_override_class_patching(self):
        # test code ...
like image 438
DurgaDatta Avatar asked Sep 23 '16 02:09

DurgaDatta


2 Answers

Use with:

def test_override_class_patching(self):
    with mock.patch('my_module.cls.method') as mock_object:
        mock_object.side_effect = RuntimeError('custom')
        # test code ...
like image 147
andydavies Avatar answered Oct 04 '22 20:10

andydavies


This can only work if the class decorator is written to account for the use of method decorators. Although the class decorator appears first, it can only run after the class object has been created, which happens after all of the methods have been defined (and decorated).

Class decorators run after method decorators, not before.

like image 20
cco Avatar answered Oct 04 '22 20:10

cco