我想模拟Pandas函数read_csv,在我的代码中,它是由一个高阶函数动态返回的,但似乎pytest patch并不真正允许它.

import pandas as pd

format_read_func_mapping = {"csv": pd.read_csv, "parquet": pd.read_parquet}

def my_func(s3_path, file_format):
    read_func = format_read_func_mapping[file_format]
    df = read_func(f"{s3_path}")
    return df

当我运行我的单元测试时,我有以下内容

from unittest.mock import patch

@patch(f"{MODULE_PATH}.pd.read_csv")
def test_my_func(self, mock_read_csv):
    mock_read_csv.side_effect = [my_test_data_frame]
    my_func(dummy_s3_path, "csv")

我预计测试将使用模拟并返回我的测试数据,但它没有,它实际上调用了pandas.read_csv来try 从dummy_s3_path读取.

但是,如果我不从映射中动态返回pd.read_csv,只需在my_func中直接使用pd.read_csv(f"{s3_path}"),模拟就可以很好地工作.

这是最热的极限吗?或者我嘲笑的方式是不正确的?

谢谢.

推荐答案

问题是您是在模块级别定义format_read_func_mapping字典,所以当导入模块时,创建字典时,键'csv'的值是对原始pd.read_csv的引用,当您随后修补pd.read_csv时,它不会被修改.

要在模块的全局命名空间中修补format_read_func_mapping,可以使用patch.dict来修补dict的特定键:

import module

@patch.dict(module.format_read_func_mapping, {"csv": Mock(side_effect=[my_test_data_frame])})
def test_my_func():
    my_func(dummy_s3_path, "csv")

Python相关问答推荐

使用plotnine和Python构建地块

如何自动抓取以下CSV

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

将整组数组拆分为最小值与最大值之和的子数组

Pandas 都是(),但有一个门槛

无法通过python-jira访问jira工作日志(log)中的 comments

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

删除字符串中第一次出现单词后的所有内容

对所有子图应用相同的轴格式

递归访问嵌套字典中的元素值

Python逻辑操作作为Pandas中的条件

使用BeautifulSoup抓取所有链接

从嵌套极轴列的列表中删除元素

一个telegram 机器人应该发送一个测验如何做?""

Python:从目录内的文件导入目录

操作布尔值的Series时出现索引问题

在matplotlib中重叠极 map 以创建径向龙卷风图

在聚合中使用python-polars时如何计算模式

使用美汤对维基百科表格进行网络刮擦未返回任何内容

如何通过函数的强式路径动态导入函数?