使用Python的Unittest框架,您如何模拟或替换具有在模块加载时运行的代码的模块?
我知道这是写得不好的代码,但这与我必须测试的代码相似。 (请参见示例)
我知道,一旦导入了模块,就可以对其进行修补以使用模拟。但是,如果有立即运行的代码怎么办?
我有一个文件需要测试。它导入的文件之一立即运行代码,请参见示例。
file_under_test.py
from somewhere.something.worker import a_func as f
class ClassToTest():
__init__(self):
...
where.something.worker模块
import os
import redis
REDIS_HOST = os.environ.get('redishost', '') #<-- Mock this
connection = redis.Redis(host=REDIS_HOST) #<--- Mock this
class AClass():
...
def a_func():
connection.doSomething()
...
答案 0 :(得分:2)
推迟创建连接,直到您真正准备好进行连接为止。另外,您可以让init_connection
进行可选的预分配连接,而不必始终按需创建。这样可以更轻松地朝着完全避免全局连接的方向迁移。
import os
import redis
connection = None
def init_connection(c=None):
global connection
if connection is None:
if c is None:
c = redis.Redis(host=os.environ.get('redishost', ''))
connection = c
...
然后,在测试模块中,您可以从init_connection
内部调用setupModule
,并选择传入所需的类似连接的对象
不必修补任何东西。
def setupModule():
init_connection()
# or
# conn = Mock()
# ... configure the mock ...
# init_connection(conn)
class ClassToTest():
__init__(self):
...