You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过tox mock awsglue模块?遇模块缺失等问题求解决方案

解决AWS Glue模块在单元测试中的导入问题

问题场景

业务代码(utils/fetch_arguments.py):

from awsglue.utils import getResolvedOptions
from functools import *

class FetchArguments:
    def __init__(self) -> None:
        pass

    def fetch_arguments(self, args):  
        # 业务逻辑代码

单元测试代码:

import unittest
from unittest.mock import patch
from utils.fetch_arguments import FetchArguments

class TestFetchArguments(unittest.TestCase):
    @patch("utils.fetch_arguments.awsglue.utils.getResolvedOptions")
    def test_fetch_arguments_with_fullload(self, mock_get_resolved_options):
        # 测试逻辑代码

通过tox运行测试时抛出错误:

from awsglue.dynamicframe import DynamicFrame
ModuleNotFoundError: No module named 'awsglue'

已尝试的无效方案

  • 安装aws-glue-libs并复制到tox的site-packages:测试可运行,但无法在CI/CD环境中自动化执行
  • 直接用python -m unittest discover -v运行:出现ModuleNotFoundError: No module named 'models'
  • 在setup.py中添加aws-glue-libs的Git地址:无法被包管理工具识别

可行解决方案

方案1:全局Mock整个AWS Glue模块

问题根源是测试执行时,项目中其他模块(如models)也导入了AWS Glue的子模块,仅Mock单个getResolvedOptions函数无法阻止真实的模块导入尝试。可以提前在测试中Mock整个awsglue包及其子模块:

修改测试文件如下:

import sys
import unittest
from unittest.mock import Mock, patch

# 提前注入Mock的awsglue模块到系统模块列表
mock_awsglue = Mock()
sys.modules['awsglue'] = mock_awsglue
sys.modules['awsglue.utils'] = mock_awsglue.utils
sys.modules['awsglue.dynamicframe'] = mock_awsglue.dynamicframe

# 现在可以安全导入被测试模块
from utils.fetch_arguments import FetchArguments

class TestFetchArguments(unittest.TestCase):
    @patch("utils.fetch_arguments.getResolvedOptions")
    def test_fetch_arguments_with_fullload(self, mock_get_resolved_options):
        # 测试逻辑示例
        mock_get_resolved_options.return_value = {"full_load": "true"}
        fetcher = FetchArguments()
        result = fetcher.fetch_arguments(["--full_load", "true"])
        self.assertEqual(result["full_load"], "true")

方案2:通过tox配置解决路径依赖(针对models模块找不到的问题)

如果直接运行测试时出现models模块找不到的问题,说明项目根目录未被加入Python路径。可以在tox.ini中配置PYTHONPATH:

[tox]
envlist = py38, py39
skipsdist = true

[testenv]
deps =
    pytest
commands =
    python -m unittest discover -v
setenv =
    PYTHONPATH = {toxinidir}

方案3:使用mock库的patch.dict批量Mock模块

也可以用patch.dict一次性Mock所有需要的AWS Glue子模块,代码更简洁:

import unittest
from unittest.mock import patch, Mock

@patch.dict('sys.modules', {
    'awsglue': Mock(),
    'awsglue.utils': Mock(),
    'awsglue.dynamicframe': Mock()
})
class TestFetchArguments(unittest.TestCase):
    @patch("utils.fetch_arguments.getResolvedOptions")
    def test_fetch_arguments_with_fullload(self, mock_get_resolved_options):
        # 测试逻辑代码
        pass

这些方案无需安装真实的AWS Glue库,完全通过Mock实现,适配本地测试和CI/CD环境。

内容的提问来源于stack exchange,提问作者whatsinthename

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:41:07