Python 单元测试:模拟从 class 对象调用的外部库函数
Python unittest: Mock an external library function called from a class object
您好,我有以下代码;
我正在尝试测试里面的加载函数file_a;下载是我导入的外部模块中的功能
file_a.py
from foo import download
class Bar()
__init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
download("latest_lib")
我写的测试像
test.py
@patch(file_a.download)
def test_download():
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
file_a.download.assert_called()
但似乎 bar 对象调用的不是模拟下载,而是导入的下载。我怎样才能解决这个问题并使我的测试通过?
我认为您缺少模拟设置:
@patch("foo.download")
def test_download(mock_download):
from file_a import Bar
Bar("latest_lib").load()
mock_download.assert_called()
我试过用你自己的代码看看哪里错了。有一些语法错误并不重要,但主要问题是您应该将字符串传递给 patch
以使其工作。
这是我对您的代码所做的修改,使这一切成为现实:
# file_a.py
from pprint import pprint as pp
class Bar():
def __init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
pp("latest_lib")
并且:
# test_file_a.py
import unittest
from unittest.mock import patch
class TestStringMethods(unittest.TestCase):
@patch("file_a.pp")
def test_download(self, pp):
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
pp.assert_called()
if __name__ == "__main__":
unittest.main()
备注:
- 您需要将字符串传递给
patch
以使其在运行时模拟对象。
- 您必须在测试函数中接收模拟对象。
- 我在这里使用了基于 class 的测试,因为我想使用
unittest
标准库,但如果您使用 [=15],则不必这样做=].
还有来自 official doc 的最后一个注释:
The basic principle is that you patch where an object is looked up,
which is not necessarily the same place as where it is defined.
您好,我有以下代码;
我正在尝试测试里面的加载函数file_a;下载是我导入的外部模块中的功能
file_a.py
from foo import download
class Bar()
__init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
download("latest_lib")
我写的测试像
test.py
@patch(file_a.download)
def test_download():
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
file_a.download.assert_called()
但似乎 bar 对象调用的不是模拟下载,而是导入的下载。我怎样才能解决这个问题并使我的测试通过?
我认为您缺少模拟设置:
@patch("foo.download")
def test_download(mock_download):
from file_a import Bar
Bar("latest_lib").load()
mock_download.assert_called()
我试过用你自己的代码看看哪里错了。有一些语法错误并不重要,但主要问题是您应该将字符串传递给 patch
以使其工作。
这是我对您的代码所做的修改,使这一切成为现实:
# file_a.py
from pprint import pprint as pp
class Bar():
def __init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
pp("latest_lib")
并且:
# test_file_a.py
import unittest
from unittest.mock import patch
class TestStringMethods(unittest.TestCase):
@patch("file_a.pp")
def test_download(self, pp):
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
pp.assert_called()
if __name__ == "__main__":
unittest.main()
备注:
- 您需要将字符串传递给
patch
以使其在运行时模拟对象。 - 您必须在测试函数中接收模拟对象。
- 我在这里使用了基于 class 的测试,因为我想使用
unittest
标准库,但如果您使用 [=15],则不必这样做=].
还有来自 official doc 的最后一个注释:
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.