如何解决Python unittest:通过模拟替换或修补一个函数
我阅读了很多关于 unittest.mock
的内容,但我无法将其转移到我自己的场景中。所以我在这里创建了一个最小的工作示例。
我只是在测试之前替换了一个函数,并在测试结束时将其设置回原始函数 - 不使用 unittest.mock
。 问题是如何使用 unittest.mock
替换函数或修改返回值。
Side-queston 是是否有办法重置测试用例末尾隐含的模拟/补丁。目前它是在 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()
显式。如果你这样做,测试类会为你做这件事:
@classmethod
def setUpClass(cls):
# ...
# start the patch
cls.patcher.start()
# stop after all tests
cls.addClassCleanup(cls.patcher.stop)
# ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。