如何在python中正确地装饰x/patched类

2024-06-03 06:29:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我想测试的自定义子类http.server.cgihttpprequesthandler. 由于cgihttpprequesthandler的init方法和所有其他方法对我的测试做了很多不相关的工作,所以我想模仿它。但是我不知道如何用@patch装饰测试的设置方法来实现这一点。 我不知道如何正确地导入/装饰修补过的类,所以我创建了一个最小的示例:

/src/samplepackage/
   tests/
      __init__.py
      sutclass_tests.py
   __init__.py
   parentclass.py
   sutclass.py

在parentclass.py公司名称:

^{pr2}$

在sutclass.py公司名称:

from samplepackage.parentclass import ParentClass

    class SUTClass (ParentClass):

    def __init__(self, a, b, c, d):
        super().__init__(a, b, c)
        self.sutAttribute = d

    def SUTmethod(self):
        self.sutAttribute = self.sutAttribute * 2
        return self.sutAttribute

萨特班_测试.py公司名称:

import unittest
from samplepackage.sutclass import SUTClass
from unittest.mock import patch
class SUTClassTests(unittest.TestCase):

    @patch("samplepackage.sutclass.SUTClass.Parent.__init__")
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.sutClass = SUTClass(1,2,3,4)

    def test_firstIteration(self):
        self.assertEqual(self.sutClass.SUTmethod(), 8)

if __name__ == '__main__':
    unittest.main()

执行sutclass_测试.py结果:

============================= ERRORS =============================
Traceback (most recent call last):
  File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched
    arg = patching.__enter__()
  File "/usr/lib/python3.5/unittest/mock.py", line 1205, in __enter__
    self.target = self.getter()
  File "/usr/lib/python3.5/unittest/mock.py", line 1375, in <lambda>
    getter = lambda: _importer(target)
  File "/usr/lib/python3.5/unittest/mock.py", line 1062, in _importer
    thing = _dot_lookup(thing, comp, import_path)
  File "/usr/lib/python3.5/unittest/mock.py", line 1051, in _dot_lookup
    __import__(import_path)
ImportError: No module named 'samplepackage.sutclass.SUTClass'; 'samplepackage.sutclass' is not a package

我明白了samplepackage.sutclass'不是包(不打算将其用作包)。将@patch decorator更改为

@patch("samplepackage.SUTClass.Parent.__init__")

产量:

============================= ERRORS =============================
Traceback (most recent call last):
  File "/usr/lib/python3.5/unittest/mock.py", line 1049, in _dot_lookup
    return getattr(thing, comp)
AttributeError: module 'samplepackage' has no attribute 'SUTClass'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched
    arg = patching.__enter__()
  File "/usr/lib/python3.5/unittest/mock.py", line 1205, in __enter__
    self.target = self.getter()
  File "/usr/lib/python3.5/unittest/mock.py", line 1375, in <lambda>
    getter = lambda: _importer(target)
  File "/usr/lib/python3.5/unittest/mock.py", line 1062, in _importer
    thing = _dot_lookup(thing, comp, import_path)
  File "/usr/lib/python3.5/unittest/mock.py", line 1051, in _dot_lookup
    __import__(import_path)
ImportError: No module named 'samplepackage.SUTClass'

所以我的问题是如何在setUp方法中正确地修补SUTClass的父类(ParentClass)(因为我想在多个测试用例中重用它)?在


Tags: inpyimportselfinitlibusrline
1条回答
网友
1楼 · 发布于 2024-06-03 06:29:37

我找到了解决我问题的How to mock a base class with python mock library。虽然不是装饰而是mock.patch.object()。 我将sutclass_tests.py改为:

import unittest
from samplepackage.sutclass import SUTClass
from unittest.mock import patch
from unittest import mock
class SUTClassTests(unittest.TestCase):

    def setUp(self):
        unittest.TestCase.setUp(self)
        patcher = patch.object(SUTClass, '__bases__', (mock.Mock,))
        with patcher:
            patcher.is_local = True
            self.sut = SUTClass(1,2,3,4)

    def test_firstIteration(self):       
        print(self.sut.SUTmethod())

if __name__ == '__main__':
    unittest.main()

这解决了我的问题(没有导入错误),并显示了使用从http.server.CGIHTTPRequestHandler派生的类测试真实场景时的正确行为

相关问题 更多 >