DurgaDatta
DurgaDatta

Reputation: 4170

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

Upvotes: 7

Views: 3236

Answers (3)

andydavies
andydavies

Reputation: 3293

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

Upvotes: 7

Dan
Dan

Reputation: 1884

I would take an entirely different approach.

class SwitchViewTest(TestCase):

  class SwitchViewStub(SwitchView):
    """ Stub out class under test """
    def __init__(self):
    """ Bypass Constructor """
      self.args = None
      ... #  Fill in the rest

  def setUp():
    self.helper = self.SwitchViewStub()
    self.helper.method_to_mock = MagicMock(...)
    ...

  def test_override_class_patching(self):
    with mock.patch.object(self.helper, 'method_to_mock', ...):
      ...

Upvotes: 0

cco
cco

Reputation: 6281

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.

Upvotes: 5

Related Questions