簡體   English   中英

python模擬補丁裝飾器對於類方法和單個函數的行為有所不同

[英]python mock patch decorator behaves different for class methods and individual functions

幾次我遇到unittest.mock.patch裝飾器的問題。 當我嘗試從包含的模塊中模擬單個功能時, patch不起作用。 但是,如果將包含的模塊中的函數收集為類方法,則patch可以完美運行。

這個問題部分與我的相交。 但是對於這個問題也沒有好的答案。

這是我要描述的示例:

|-- __init__.py
|-- helpers.py
|-- main_module.py
|-- tests.py

我在helpers.py編寫了一個函數作為類方法,而另一個則helpers.py為單個函數:

# helpers.py
class HelperClass():

    def method_a(self):
        return "a"

def function_a():
    return "a"

我已經將它們都包含在主模塊中:

# main_module.py    
from helpers import HelperClass, function_a


    def function_which_uses_helper_function():
        a_val = function_a()
        return a_val

    def function_which_uses_helper_class_method():
        a_val = HelperClass().method_a()
        return a_val

最后測試:

# tests.py
from unittest import TestCase
from unittest.mock import patch
from main_module import function_which_uses_helper_function, function_which_uses_helper_class_method


class TestClass(TestCase):

    @patch('helpers.function_a')
    def test_function_which_uses_helper_function(self, mock_function_a):
        mock_function_a.return_value = "c"
        self.assertEqual(function_which_uses_helper_function(), "c")

    @patch('helpers.HelperClass.method_a')
    def test_function_which_uses_helper_class_method(self, mock_method_a):
        mock_method_a.return_value = "c"
        self.assertEqual(function_which_uses_helper_class_method(), "c")

這給了我這些結果:

$ py.test tests.py
<...>
tests.py .F
<...>
tests.py:11: in test_function_which_uses_helper_function
    self.assertEqual(function_which_uses_helper_function(), "c")
E   AssertionError: 'a' != 'c'
E   - a
E   + c
============ 1 failed, 1 passed in 0.14 seconds ============

我將不勝感激。 希望這也可以幫助某人:)

一段時間后,我終於明白了為什么我的函數示例不起作用。 解釋在這里 這篇文章也非常有用。 考慮所有解決方案將是:

# main_module.py    
import helpers # <- I had to change my import statement


def function_which_uses_helper_function():
    a_val = helpers.function_a()
    return a_val

def function_which_uses_helper_class_method():
    a_val = helpers.HelperClass().method_a()
    return a_val

另一個解決方案是更改模擬我的function_a的方式,即:

from unittest import TestCase
from unittest.mock import patch
from main_module import function_which_uses_helper_function, function_which_uses_helper_class


class TestClass(TestCase):

@patch('main_module.function_a') # <-- !!! I need to mock function in the`main_module`, not in `helpers` !!!
def test_function_which_uses_helper_function(self, mock_function_a):
    mock_function_a.return_value = "c"
    self.assertEqual(function_which_uses_helper_function(), "c")

@patch('helpers.HelperClass.function_a')
def test_function_which_uses_helper_class(self, mock_function_a):
    mock_function_a.return_value = "c"
    self.assertEqual(function_which_uses_helper_class(), "c")

我最近才意識到所有這些,對此我感到很難過。 希望這對某人有幫助:)

暫無
暫無

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

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