簡體   English   中英

Python:在測試函數的同一模塊中定義的修補函數

[英]Python: patching function defined in same module of tested function

我一直在使用 Python 的unittest.mock庫,但現在我正在為一個可能無法正確處理的用例而苦苦掙扎。

考慮一個包含以下代碼段的文件mymodule/code.py

def sum():
  pass

def mul():
  pass

def div():
  pass

def get_functions():
  return [sum, mul, div]

def foo():
  functions = get_functions()
  for func in functions:
    func()

我想測試foo函數,修補sum函數,並將muldiv原樣。 這是我最初嘗試的:

class TestFoo(unittest.TestCase):
  @mock.patch('mymodule.code.foo.sum')
  def test_foo(foo_sum_mock):
    foo()
    foo_sum_mock.assert_called_once()

但是,上面說明的修補方法不起作用。 我相信sum函數在加載mymodule.code.py時被正確修補,但由於def sum()塊而重新定義。

通過閱讀官方文檔,我也嘗試使用unittest.mock庫的startstop功能如下:

def test_foo():
  patcher = mock.patch('module.code.sum')
  mocked_sum_fun = patcher.start()

  foo()

  mocked_sum_fun.assert_called_once()
  mock_sum_fun.stop()

這種方法也行不通。 我希望在加載modules/code.py文件后它會避免sum函數覆蓋。

是否可以修補諸如sum類的局部函數? 或者將sum函數移動到另一個文件是修補的唯一選擇?

提前謝謝了!

您可以使用mock.patch模擬同一模塊的函數並將此模塊稱為__main__

代碼.py

from unittest.mock import patch

def sum():
    print("called method sum")
    pass

def call_sum():
    sum()

def return_mock():
    print("I'm a mocked method")
    return True

with patch('__main__.sum', return_value=return_mock()) as mock_test:
    call_sum()
    mock_test.assert_called_once() # assure that mocked method was called, not original.

您還可以使用 lib ( my_project.code.sum ) 的路徑而不是__main__.sum

一般來說,您希望將測試代碼與生產代碼分開:

代碼.py

def sum():
    pass

def mul():
    pass

def div():
    pass

def get_functions():
    return [sum, mul, div]

def foo():
    functions = get_functions()
    for func in functions:
        func()

代碼測試.py

import unittest
import mock_test as mock
import code

class TestFoo(unittest.TestCase):
    @mock.patch('code.sum')
    def test_foo(self, sum_mock):
        def new_sum_mock(*args, **kwargs):
            # mock code here
            pass
        sum_mock.side_effect = new_sum_mock
        code.foo()
        sum_mock.assert_called_once()

但是,是的,您可以將其全部放入一個文件中:

代碼_test.py:

import unittest
import mock_test as mock
import code

def sum():
    pass


def mul():
    pass


def div():
    pass


def get_functions():
    return [sum, mul, div]


def foo():
    functions = get_functions()
    for func in functions:
        func()


class TestFoo(unittest.TestCase):

    @mock.patch('code_test.sum')
    def test_foo(self, sum_mock):
        def new_sum_mock(*args, **kwargs):
            # mock code here
            pass

        sum_mock.side_effect = new_sum_mock
        code.foo()
        sum_mock.assert_called_once()

暫無
暫無

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

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