您如何立即测试 运行 的代码?

How do you test code that is run Immediately?

使用 Python 的 Unittest 框架,如何模拟或替换模块加载时代码为 运行 的模块?

我知道这是写得不好的代码,但这与我要测试的代码相似。 (参见示例)

我知道一旦导入了一个模块,就可以对其进行修补以使用模拟。但是,如果有立即 运行 的代码怎么办?

我有一个文件需要测试。它立即导入 运行 代码的文件之一,请参见示例。

file_under_test.py

from somewhere.something.worker import a_func as f

class ClassToTest():
    __init__(self):
...

somewhere.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()
    ...

推迟创建连接,直到您真正准备好创建连接。作为奖励,您可以让 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

...

然后,在您的测试模块中,您可以从 setupModule 内部调用 init_connection,并可选择传入所需的类似连接的对象 而不是必须修补任何东西。

def setupModule():
    init_connection()
    # or
    # conn = Mock()
    # ... configure the mock ...
    # init_connection(conn)

class ClassToTest():
    __init__(self):
...