Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以在setUpClass中模拟多个测试用例吗?_Python_Unit Testing_Mocking - Fatal编程技术网

Python 我可以在setUpClass中模拟多个测试用例吗?

Python 我可以在setUpClass中模拟多个测试用例吗?,python,unit-testing,mocking,Python,Unit Testing,Mocking,我在每个测试用例中都使用模拟装饰器。有没有办法将decorator合并到setUpClass 我的单元测试就像: class TestCase(): @mock.patch('some.path.config') def测试案例001(自身、模拟案例): mock_cfg.return_value='value' ... @mock.patch('some.path.config') def测试案例002(自身、模拟案例): mock_cfg.return_value='value' ... @

我在每个测试用例中都使用模拟装饰器。有没有办法将decorator合并到
setUpClass

我的单元测试就像:

class TestCase():
@mock.patch('some.path.config')
def测试案例001(自身、模拟案例):
mock_cfg.return_value='value'
...
@mock.patch('some.path.config')
def测试案例002(自身、模拟案例):
mock_cfg.return_value='value'
...
@mock.patch('some.path.config')
def测试案例003(自身、模拟案例):
mock_cfg.return_value='value'
...
我可以合并到一个,就像:

class TestCase():
@mock.patch('some.path.config')
@类方法
def设置类(cls、模拟cfg):
mock_cfg.return_value='value'
通过
def测试案例001(自身):
通过
def测试案例002(自身):
通过
def测试案例003(自身):
通过

只需设置模拟并使用
self

class TestName(TestCase):
    @mock.patch('some.path.config')
    def setUp(self, mock_cfg):
        self.mock_cfg = mock_cfg
        self.mock_cfg.return_value = 'value'
        ...

    def test_case_001(self):
        ... # use self.mock_cfg

    def test_case_002(self):
        ... # use self.mock_cfg

    ...

使用这样的方法,应该是有用的

class TestDemo(test.TestCase):
    def setUp(self):
        super(TestDemo, self).setUp()
        self.mocks = [(mock.patch('a.methodB',
                                mock.MagicMock(return_value=None)))]
        for single_mock in self.mocks:
            single_mock.start()
            self.addCleanup(single_mock.stop)


有不同的方法可以做到这一点。下面是我目前在python2和python3中使用的技巧

假设我们将模拟名为
get_val
的函数,以返回
yes

#data.py
def get_val():
返回“否”
我将在演示代码中使用
setUp
,但同样的技巧也适用于
setUpClass

1.最简单的方法:在测试类上使用mock
#test_data.py
#模拟值是固定的
@补丁('data.get_val',MagicMock(return_value='yes'))#固定值
类TestFoo(TestCase):
def设置(自):
打印(data.get_val())#否
def测试用例(自身):
打印(data.get_val())#是
#每个测试用例设置的模拟值
@修补程序('data.get_val')
类TestBar(TestCase):
def设置(自):
打印(data.get_val())#否
def测试用例(自我、模拟获取值):
mock_get_val.return_value='yes'#在每种情况下设置值
打印(data.get_val())#是
优点:

  • 简单的
缺点:

  • 设置中未模拟目标
  • 您只能选择使用固定值模拟目标,或者在每个测试用例中提供模拟值。完全没有混合使用
2.最灵活的方法:手动启动模拟
#test_data.py
类TestCool(TestCase):
def设置(自):
self.mocks=[patch('data.get_val',MagicMock(return_value='yes'))]#固定值
对于self.mock中的mock:
mock.start()
打印(data.get_val())#是
def拆卸(自):
对于self.mock中的mock:
mock.stop()
def测试用例(自身):
打印(data.get_val())#是
def测试箱冷却(自):
self.mocks[0]。返回值='cool'#仅在这种情况下覆盖模拟
打印(data.get_val())#酷
优点:

  • 您可以在
    setUp
    s中获得模拟作品
  • 您可以混合使用mock和预先提供的固定值,或者根据每个测试用例提供mock值
  • 更容易管理成吨的模拟,因为您可以编写代码来控制它们
缺点:

  • 即使是简单的任务也需要编写更多的代码

奖金提示: 不要直接在
setUp
上使用
patch
,因为修改
setUp
s的签名会导致PyCharm抱怨:

方法“TestMockedSetup.setUp()”的签名与类“TestCase”中基方法的签名不匹配

更严重的是,模拟只在
设置
中工作,并且在您的测试用例中会恢复为unmocked,这可能不是您想要的