如何在一个脚本中模拟另一个运行第一个脚本的测试脚本中的类



我在一个单独的脚本SQLES .py中有一个类SQLES,它是在main.py中导入的,包含读取SQL数据和在类实例中设置结果的方法。

我现在正在编写一个测试脚本test_main.py,我想在其中定义一个模拟SQLES类,以供main.py透明地使用,而不是真正的SQLES。我不测试SQLES本身,模拟类的思想是包含相同的方法集,但返回硬编码的数据行列表。

我已经搜索了几个小时,但在python/mock/etc上没有一个结果解释如何设置这个显然非常简单的要求。这是我到目前为止准备的测试脚本(为了清晰起见,截断了):

import unittest.mock
import main    # main.py script I wish to run with the mocked SQLES class
class MockSQLES: # Dummy class I wish main.py to instantiate and use instead of SQLES
def __init__(self):
return
def init(self, logger, cmd_args_record, cmd_args_playback):
return
# Couple of specimen methods, to give an idea of what dummy SQL class does ..
def get_exchange_rates(self):
self.exchange_rates['GBP'] = [
[ '2021-09-13', 0.722298 ],
[ '2021-08-20', 0.734203 ]
]
return
def get_firms_names_other(self):
self.firms_names_other[firm_id] = [
[ 131, 'Acme Industries' ],
[ 132, 'Acme Research'   ]
]
return
::::
with unittest.mock.patch('main.SQLES') as MockSQLES:
main.main()

但是当我尝试运行它时,在实例分配后打印调试信息:

sql = SQLES()

显示结果sql对象的类型为unittest.mock.MagicMock,而不是我所期望的MockSQLES,并且后者中的方法没有被调用。

总之,我想知道如何解决这个问题。也许Mock是错误的方法,还有其他方法(猴子补丁?)更适合这个

另外,我不希望对main.py脚本进行任何不必要的修改。(很明显,如果main.py有一个测试标志或类似标志来创建SQLES或MockSQLES的实例,那么如何使用模拟SQL类。)

您没有使用模拟类。当您执行以下操作时:

with unittest.mock.patch('main.SQLES') as MockSQLES:

上下文管理器unittest.mock.patch产生的响应将分配给as子句变量MockSQLES。所以这里的MockSQLES实际上不是模拟类,而是补丁的屈服响应。你可以试着这样做:

with unittest.mock.patch('main.SQLES', MockSQLES) as mock_sql:

用于unittest.mock的参考。第一个参数是补丁SQLES的功能,而第二个参数是文档中MockSQLES的替换:

unittest.mock.patch(target, new=DEFAULT, ...)

被一个新的修补对象

请务必阅读关于Mocking Classes的进一步参考。

最新更新