【问题标题】:python mocking function calls that are called during module import在模块导入期间调用的 python 模拟函数调用
【发布时间】: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


【解决方案1】:

在这种情况下,您可以做的是使用 mock.patch.dict 修补 config 实例:

# test_coolio.py
import mock
from app.fun import coolio


@mock.patch.dict('app.configparser.config', values={'config': {'a': 15}})
def test_config_mock():
    assert coolio() == '15'


# app/fun.py
from app.configparser import config


def coolio():
    return config['config']['a']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多