【发布时间】:2020-04-18 15:20:57
【问题描述】:
我需要对模块导入期间运行的 python 代码执行模拟
例如我有这样的代码
import configparser
config = configparser.ConfigParser()
config.read('test.ini')
a = float(config['config']['a'])
b = float(config['config']['b'])
c = float(config['config']['c'])
print(a)
print(b)
print(c)
我需要模拟“配置”进行测试
import pytest
import mock
import app
@mock.patch('app.configparser.ConfigParser')
def test_config_mock(config_mock):
config_mock.return_value = {'config': { 'a' : 1 } }
但是,这个测试函数是在实际导入之后调用的,所以我的模拟没有任何意义
做这种事情的正确方法是什么?
【问题讨论】:
-
正确的做法是在导入时不。公开一个这样做的函数,然后调用它
if __name__ == •"__main__":。 -
@jonrsharpe ,抱歉,我不确定我是否理解嘲弄问题与您的回答有何关系。如果我将 import 语句放入函数并从 if name == "main" 进行函数调用,我会遇到同样的问题。该模块将在实际测试功能执行之前加载。
-
我并不是说在测试中的函数中导入导入,如果这就是你的意思的话;我是说修改
app.configparser,这样您就可以在不立即执行的情况下导入它的功能。 -
@jonsharpe,好的,现在很清楚,您的意思是修改被测代码。但同样,这似乎也行不通。 A,B,C 变量将仅在 if 的范围内定义,但它们用于此模块的其他功能。这意味着重构模块代码,这不是有利的选择。如果可能的话,您能否发布一个代码 sn-p(可能是伪代码)?
-
当然是重构模块代码。您编写了不可测试的代码;如果你想测试它,你需要重构它。
标签: python-3.x unit-testing mocking pytest python-mock