假设我有一个如下所示的类:
class SampleClass(object):
def __init__(self):
self.ops = {
'key 1': self.function_a,
'key 2': self.function_b
}
def function_a(self):
print('Inside a')
def function_b(self):
print('Inside b')
def main(self, key):
self.ops[key]()
根据我得到的密钥,我选择并执行两个函数中的任何一个。
我正在尝试对主要功能进行单元测试,但我无法对function_a
或function_b
进行修补。
我在一个名为test.py
的单独文件中编写单元测试。
当我尝试使用:
修补function_a时self.sampleclass = SampleClass()
with patch.object(SampleClass, 'function_a', return_value=None) as test_function:
self.sampleclass.main('key1')
控件进入function_a
并打印Inside a
。
如何模拟从函数dict调用的函数?
答案 0 :(得分:1)
可以修补字典条目,这里的示例与您发布的内容非常相似:
from mock import patch, Mock
class SampleClass():
def __init__(self):
self.ops = {
'key 1': self.function_a,
'key 2': self.function_b
}
def function_a(self):
print('Inside a')
def function_b(self):
print('Inside b')
def main(self, key):
self.ops[key]()
test_function = Mock(name='mock_a')
sampleclass = SampleClass()
with patch.dict(sampleclass.ops, {'key 1': test_function}):
sampleclass.main('key 1')
test_function.assert_called_once()
我认为您也可以在创建实例之前修补SampleClass
来解决问题。
但是,我建议你考虑嘲笑function_a()
的一部分,而不是试图模仿整个事情。这将更容易理解,并且可能将模拟对象放在被测系统及其依赖项之间的更好的接缝中。
例如,假设您的SampleClass
需要模拟,因为它登录到Web服务然后发送多个请求。如果function_a()
在发出请求之前调用了self.login()
,那么您可以模拟SampleClass.login()
。
from mock import patch
class SampleClass():
def __init__(self):
self.ops = {
'key 1': self.function_a,
'key 2': self.function_b
}
def login(self):
session = None
# session = service.login(username, password)
return session
def function_a(self):
session = self.login()
session.send('Inside a')
def function_b(self):
session = self.login()
session.send('Inside b')
def main(self, key):
self.ops[key]()
sampleclass = SampleClass()
with patch('__main__.SampleClass.login') as test_function:
sampleclass.main('key 1')
test_function.assert_called_once()
test_function.return_value.send.assert_called_once_with('Inside a')