首页 > 解决方案 > 你如何测试立即运行的代码?

问题描述

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

我知道这是写得很糟糕的代码,但这与我必须测试的类似。(见示例)

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

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

file_under_test.py

from somewhere.something.worker import a_func as f

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

某处.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()
    ...

标签: pythonpython-unittest

解决方案


推迟创建连接,直到您真正准备好它的发生。作为奖励,您可以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从 inside调用setupModule,并可以选择传入所需的类似连接的对象,而不必修补任何东西。

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

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

推荐阅读