python / python/cpython

Unittest Patch only works on attributes, methods

未关闭
#129,629 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

stdlib type-bug
主要语言
Python
星标
77.2k
派生
36k
PR 合并指标
PR 指标待抓取

描述

Bug report

Bug description:

I am having an issue where the patch method from the unittest.mock module is only working when I patch attributes of imported modules in other files. I do not understand if this is an issue of my import patterns or a misunderstanding of how patching works. (I am importing the app code before the patch is able to run).

I devised a test to show how the functionality is confusing me:

In my app code I have the following code

    from datetime import date
    ...
    import boto3
    ...
    from common.functions import asodates2datetime
    from core.mixins.usecases import ASOUsecaseTools


    class foo:
        @staticmethod
        @ASOUsecaseTools.get_by_name
        def bar(self, relevant_date):
            client = boto3.client("s3")
            today = date.today()
            date = asodates2datetime(relevant_date)

And from my test code I can patch in the following way:

    @mock.patch("src.aoi.usecases.date")
    @mock.patch("src.aoi.usecases.ASOUsecaseTools.get_by_name")
    @mock.patch("src.aoi.usecases.asodates2datetime")
    @mock.patch("src.aoi.usecases.boto3.client")
    def test_foo_gets_bar(self, m_d, m_g, m_a, m_c):
        m_d.today.return_value = <date>
        m_d.side_effect = lambda *args, **kw: date(*args, **kw)
        # more patching of functions here

However, when the test is run, If I set a breakpoint in the bar function and check the value of the patched items, only the patched methods show up as MagicMock

    >>> boto3.client
        <MagicMock name='client...>
    >>> ASOUsecaseTools.get_by_name
        <MagicMock name='get_by_name...>
    >>> asodates2datetime
        <function asodates2datetime...>
    >>> date
        <class 'datetime.date'>

The thing that confuses me is that I am patching along with how the docs say to patch: https://docs.python.org/3/library/unittest.mock-examples.html#partial-mocking

Also the fact that patched methods work but classes and functions don't indicates that the import structure is not a problem because the imported methods would be overwritten in the same way as the imported classes. It also indicates that the import paths are not incorrect; as the only difference between the patches is the type of object they are patching.

My current workaround is using the freeze package to freeze the date, but I prefer using builtin packages if possible.

CPython versions tested on:

3.9

Operating systems tested on:

macOS

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 issue 中提供的 unittest.mock 复现代码开始,并将其 patch 目标与链接的 partial mocking 文档进行比较。在 CPython 3.9 上验证行为,然后确定观察到的差异究竟是可复现的解释器 bug,还是对 import/patching 的误解;一个具体的失败测试和预期行为将定义完成标准。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
testing-qa
Issue 类型
缺陷
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
需要澄清
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。