用方法补丁(装饰器)覆盖 class 补丁

Override the class patch with method patch (decorator)

我在 class 中有几个测试方法,它们对对象使用一种类型的修补程序,因此我使用 class 装饰器进行了修补。对于另一种方法,我想以不同的方式修补同一个对象。我尝试了以下方法,但是尽管方法本身被不同的补丁装饰,但作为 class 装饰器制作的补丁仍然有效。我希望方法补丁可以覆盖 class 补丁。为什么不是这样?

在这种特殊情况下,我可以删除 class 补丁和补丁个别方法,但那将是重复的。我如何实现这种覆盖(方法覆盖 class 补丁)机制?

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

这只有在编写 class 装饰器以说明方法装饰器的使用时才有效。尽管 class 装饰器首先出现,但它只能在 class 对象创建后 运行 出现,这发生在所有方法都已定义(和装饰)之后。

Class 装饰器 运行 方法装饰器之后,而不是在之前。

我会采取完全不同的方法。

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', ...):
      ...

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