簡體   English   中英

mock.patch忽略完全導入函數的原因是什么?

[英]What is the reason that mock.patch ignores a fully imported function?

今天我意識到unittest.mock.patch對於如何導入函數很重要。 根據使用的方式, mock.patch調用工作或被忽略。 在Python中,我們通常導入一個函數:

  • 導入語句,如import os
  • from os import systemfrom ... import ...語句

如果我使用import osmock.patch就像魅力一樣,但如果我from os import system修補它,它就會被忽略。

示例1:使用導入

import os
from unittest import mock


def echo():
    os.system('echo "Hello"')


with mock.patch('os.system') as mocked:
    print(mocked)
    mocked.side_effect = Exception('Patch works!')
    echo()

示例1的輸出

<MagicMock name='system' id='140037358656760'>

Traceback (most recent call last):
  File "/.../config/scratches/scratch_7.py", line 12, in <module>
    echo()
  File "/.../config/scratches/scratch_7.py", line 6, in echo
    os.system('echo "Hello"')
  File "/.../python3.5/unittest/mock.py", line 917, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/.../python3.5/unittest/mock.py", line 973, in _mock_call
    raise effect
Exception: Patch works!

示例2:使用完整功能導入和從導入

當我完全導入os.systemmock.patch忽略mocked.side_effect

from os import system
from unittest import mock


def echo():
    system('echo "Hello"')


with mock.patch('os.system') as mocked:
    print(mocked)
    mocked.side_effect = Exception('Patching does not work!')
    echo()

    print('Patch was ignored!')

例2的輸出

<MagicMock name='system' id='139851175427376'>
Hello
Patch was ignored!

在這兩種情況下,我都沒有收到錯誤,並且mock可以找到os.system作為有效路徑。 但是,在第二種情況下,功能未正確修補。

  • 為什么mock.patch不修補第二個例子中的函數?
  • 是否有任何特定於實現的原因導致第二個補丁不起作用?

from os import system ,會得到一個名為system的變量,指向os.system函數。 稍后,通過修補為os.system 分配一個不同的函數,但system會指向舊函數。 這與以下工作原理相同:

tmp = a
a = b
b = tmp

在第一個示例中不會發生這種情況,因為在os.system之前引用os.system 要修復你的第二個例子,我將使用以下內容:

from os import system
from unittest import mock

def echo():
    system('echo "Hello"')

with mock.patch('__main__.system') as mocked:
    print(mocked)
    mocked.side_effect = Exception('Patching does not work!')
    echo()

    print('Patch was ignored!')

這樣您就可以確保修補正確的參考。 這是一種相當常見的模式。 如果echo函數位於名為echo.py的文件中,則補丁調用看起來with mock.patch('echo.system')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM