我在每个测试用例中都使用模拟装饰器。我可以将装饰器合并到setUpClass
吗?
我的单元测试就像:
class TestCase():
@mock.patch('some.path.config')
def test_case_001(self, mock_cfg):
mock_cfg.return_value = 'value'
...
@mock.patch('some.path.config')
def test_case_002(self, mock_cfg):
mock_cfg.return_value = 'value'
...
@mock.patch('some.path.config')
def test_case_003(self, mock_cfg):
mock_cfg.return_value = 'value'
...
我可以像这样将模拟合并到一个吗
class TestCase():
@mock.patch('some.path.config')
@classmethod
def setUpClass(cls, mock_cfg):
mock_cfg.return_value = 'value'
pass
def test_case_001(self):
pass
def test_case_002(self):
pass
def test_case_003(self):
pass
答案 0 :(得分:0)
只需设置模拟并使用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
...
答案 1 :(得分:0)
使用这种方法应该很有用。
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)
答案 2 :(得分:0)
有不同的方法可以做到这一点。以下是我目前在python2和python3上都使用的技巧。
假设我们要模拟名为get_val
的函数以返回yes
:
# data.py
def get_val():
return 'no'
我将仅在演示代码中使用setUp
,但同样的技巧也应与setUpClass
一起使用。
# test_data.py
# mock value is fixed
@patch('data.get_val', MagicMock(return_value='yes')) # fixed value
class TestFoo(TestCase):
def setUp(self):
print(data.get_val()) # no
def test_case(self):
print(data.get_val()) # yes
# mock value set by each test case
@patch('data.get_val')
class TestBar(TestCase):
def setUp(self):
print(data.get_val()) # no
def test_case(self, mock_get_val):
mock_get_val.return_value = 'yes' # set value in each case
print(data.get_val()) # yes
优点:
缺点:
setUp
中未模拟目标# test_data.py
class TestCool(TestCase):
def setUp(self):
self.mocks = [patch('data.get_val', MagicMock(return_value='yes'))] # fixed value
for mock in self.mocks:
mock.start()
print(data.get_val()) # yes
def tearDown(self):
for mock in self.mocks:
mock.stop()
def test_case(self):
print(data.get_val()) # yes
def test_case_cool(self):
self.mocks[0].return_value = 'cool' # override the mock only for this case
print(data.get_val()) # cool
优点:
setUp
s内获得模拟作品缺点:
请勿直接在patch
上使用setUp
,因为修改setUp
的签名会导致PyCharm抱怨:
方法'TestMockedSetup.setUp()'的签名与类'TestCase'中的基本方法的签名不匹配
更严重的是,该模拟只能在setUp
内运行,并且会在测试用例中恢复为未模拟,这可能不是您想要的。