python / python/cpython

Unittest Patch only works on attributes, methods

オープン
#129,629 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

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. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Issue に提供されている unittest.mock の再現コードから始め、その patch 対象をリンク先の partial mocking に関するドキュメントと比較してください。CPython 3.9 での動作を確認し、その後、観測された差異が再現可能なインタープリターのバグなのか、import や patch に関する誤解なのかを明らかにしてください。具体的に失敗するテストと期待される動作があれば、完了の定義になります。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
testing-qa
issue の種類
バグ
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。