gpt4 book ai didi

python - 在未知子包中模拟 urlopen

转载 作者:行者123 更新时间:2023-12-05 06:36:57 26 4
gpt4 key购买 nike

我想模拟模块中对 urllib.request.urlopen 的调用。当它是单个文件时它可以工作,但是当我把它放在一个包中并在包的 __init__.py 中导入模块时,我不能再模拟它了。

复制

假设我在一个test 包中有两个模块:

  • module.py

    from urllib.request import urlopen

    def do_it():
    print(urlopen.__module__)
    urlopen('test')
  • module_test.py

    from unittest import mock
    from .module import do_it


    def test_not_working():
    with mock.patch('urllib.request.urlopen', lambda url: print(url)):
    do_it()


    def test_plain():
    with mock.patch('test.module.urlopen', lambda url: print(url)):
    do_it()

test_not_working 打印 urllib.request 作为 urlopen 的模块,因为我修补了本地 urlopen 函数测试模块,测试失败,因为 test 不是有效的 URL。
test_plain 打印.module,因为我成功修补了urlopen,测试成功并打印了test

我的问题是我已将 .module 移动到一个包中,因为我想对我创建的多个文件进行分组。现在看起来像这样:

  • 模块

    • __init__.py

      from .module import do_it
    • module.py(与之前的module.py相同)
  • test_module.py

    from unittest import mock
    from .module import do_it


    def test_packaged_fails():
    with mock.patch('test.module.urlopen', lambda url: print(url)):
    do_it()

    def test_packaged_works():
    with mock.patch('test.module.module.urlopen', lambda url: print(url)):
    do_it()

前两个测试保持不变,但是 test_packaged 打印 urllib.request,并且作为第一个测试失败,因为 URL test 是无效。

我知道我没有模拟 urlopen,因为它显然不使用 test.module.urlopentest.module.module.urlopen.

限制

实际项目

我不知道如何解决这个问题,因为该模块只是开源项目 (OpenMensa Parsers) 中的众多模块之一。 Aachener parser是一个包含多个文件的包,而不是像其他解析器那样的单个文件模块。
当我想upgrade snapshots时出现上述问题用于我们的回归测试。它应该缓存解析器发出的所有请求,以便以后可以重现测试,即使网站发生变化也是如此。

列表

我有以下限制:

  • 我不能硬编码子模块的路径 (test.module.module.urlopen),因为我也想为其他解析器使用快照生成。
  • 由于构建系统和部署的原因,我只能使用作为 Debian Wheezy 软件包提供的库。 See the currently installed dependencies.
  • 为了与其他解析器保持一致,我想继续使用 urllib.request.urlopen
  • 我实际上并没有直接调用do_it()。我从另一个模块调用一个函数,该模块从不同的解析器模块动态导入 do_it() 然后调用它。为简单起见,我将保留上面的最小示例。

问题

如果我不知道调用它的子包,如何在包中修补 urlopen

最佳答案

解决方法是修改 module/module.py 中的 import 语句:

from urllib import request

def do_it():
print(urlopen.__module__)
request.urlopen('test')

这使得模拟它成为可能:

with mock.patch('urllib.request.urlopen', lambda url: print(url)):
do_it()

不过,这是一种变通方法,需要更改被测模块。我仍然对找到直接导入 urlopen 的子模块并在那里模拟它的方法感兴趣。

关于python - 在未知子包中模拟 urlopen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48614058/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com