python-3.x - Python unittest:通过模拟替换(或修补)函数
问题描述
我读了很多关于unittest.mock
但我无法将其转移到我自己的场景中。所以我在这里创建了一个最小的工作示例。
我只是在测试之前替换一个函数,然后在测试结束时将其设置回原来的函数——而不使用unittest.mock
. 问题是如何使用unittest.mock
.
附带问题是是否有一种方法可以重置 TestCases 末尾隐含的模拟/补丁。目前它在tearDownClass()
. 但有时我会忘记这样的事情。
#!/usr/bin/env python3
class MyData:
me = None
def __init__(self):
MyData.me = self
self.data = self._get_default_data()
def _get_default_data(self):
return "real default data"
if __name__ == '__main__':
MyData()
print(MyData.me.data)
这是测试
import unittest
from mockplay import MyData
def _test_data(self):
return "simulated test data"
class MyTest_Sim(unittest.TestCase):
@classmethod
def setUpClass(cls):
# remember the original method
cls.org_method = MyData._get_default_data
# mock the method
MyData._get_default_data = _test_data
MyData()
@classmethod
def tearDownClass(cls):
# rest the mock/patch to the origiinal
MyData._get_default_data = cls.org_method
def test_data(self):
self.assertEqual(MyData.me.data,
"simulated test data")
背景资料:
真正的应用程序从 JSON 文件中读取与用户相关的内容(例如电子邮件)。第一次启动,直接安装后,没有这个json文件。因此,应用程序使用“内置”默认 JSON 文件。每个测试都从一个“新”应用程序开始——文件系统上没有 JSON 文件。所以它使用_get_default_data()
. 为了控制测试中存在哪些数据,我需要模拟/修补/替换此方法,因为默认 JSON 文件 a) 不适合所有测试用例,并且 b) 在应用程序开发过程中可能会发生变化。
解决方案
无需更换功能。在我的示例中,仅对函数的返回值感兴趣。
补丁被创建并且显式开始于setupClass()
和显式停止于tearDownClass()
。
import unittest
import unittest.mock as mock
from mockplay import MyData
class MyTest_Sim(unittest.TestCase):
@classmethod
def setUpClass(cls):
# mock the return value
cls.patcher = mock.patch('mockplay.MyData._get_default_data',
return_value='simulated test data')
# start the patch
cls.patcher.start()
# initiate data
MyData()
@classmethod
def tearDownClass(cls):
# stop the patch
cls.patcher.stop()
def test_data(self):
self.assertEqual(MyData.me.data,
"simulated test data")
Python 3.8 或更新版本
在这个 Python 版本中addClassCleanup()
,引入了新方法。所以你不需要注意patcher.stop()
在所有测试结束时调用explicite。如果您这样做,测试类将为您执行此操作:
@classmethod
def setUpClass(cls):
# ...
# start the patch
cls.patcher.start()
# stop after all tests
cls.addClassCleanup(cls.patcher.stop)
# ...
推荐阅读
- machine-learning - 多个变量的梯度下降失败,导致 NaN
- javascript - 如何执行 javascript 以使用 python 和 selenium 更改日期
- ruby - Ruby PTY 生成左伪终端设备文件已打开
- matlab - Matlab逐步Logistic人口增长模拟
- android - Xamarin 移动应用程序中的类似网站的导航
- ajax - Ajax 返回 PUT ... 405(不允许的方法)
- python - 尝试对 ndarray 中的值进行舍入时出错
- python-3.x - 使用 Python 复制和粘贴具有相似但不确切名称的文件
- javascript - MongoDB/Mongoose:多个级别的子文档/嵌套对象
- groovy - 如何根据两个键对映射值求和?