对于单元测试包装器库的情况,目标是在不依赖/执行上游库的情况下测试包装器;在已知的情况下,可以对所有对上游库的调用进行模拟,而这就是我所做的,但是我对包装程序的更改感到沮丧,因为包装程序的引入使模拟工具错过了对上游库的更多调用; >
如何最好地通过任何尝试使用给定名称空间的测试?
我目前的想法是将所有unittest方法更改为具有猴子补丁之类的
@unittest.mock.patch('wrapper_namespace.upsteam_namespace')
并使用可以被断言的模拟回复上游库;我希望有一个可以在全球范围内使用的选项,这样我
答案 0 :(得分:1)
您不必修补所有测试方法。如果您使用的是class
,则可以轻松地对unittest
进行修补,也可以将模块分配给要对其进行修补的对象。这是一个可行的示例:
some_lib.py中的假库:
def some_lib_func():
raise ValueError("I've been called.")
def some_other_lib_func():
raise ValueError("I've been called.")
class SomeClass:
def __init__(self):
raise ValueError("I've been constructed.")
wrapper.py:
import some_lib
def wrapper1():
some_lib.some_lib_func()
def wrapper2():
some_lib.some_other_lib_func()
def wrapper3():
x = some_lib.SomeClass()
test.py:
from unittest.mock import patch, MagicMock
import unittest
import wrapper
# Alternative:
# wrapper.some_lib = MagicMock()
# Can patch an entire class
@patch('wrapper.some_lib', MagicMock())
class TestWrapper(unittest.TestCase):
def test_wrapper1(self):
wrapper.wrapper1()
def test_wrapper2(self):
wrapper.wrapper2()
def test_wrapper3(self):
wrapper.wrapper3()
if __name__ == "__main__":
unittest.main()
如果调用some_lib
中的函数/类,我们会爆炸,但事实并非如此:
Matthews-MacBook-Pro:stackoverflow matt$ python test.py
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
可以随时对补丁进行注释,并在wrapper.some_lib = MagicMock()
中进行注释。在这个玩具示例中,您将获得相同的结果,但是两种方法之间存在主要差异:
使用时 @patch('wrapper.some_lib', MagicMock())
该修补程序仅适用于该测试用例类。
使用 wrapper.some_lib = MagicMock()
时,该补丁将在整个python程序的长度范围内保持有效 ,除非您保存原始模块并在某个时候手动将其修补。使用wrapper
模块的所有内容都会获得模拟版本。
所以您可以这样:
original_lib = wrapper.some_lib
wrapper.some_lib = MagicMock()
...
# call some test suite, every call to the wrapper module will be mocked out
...
wrapper.some_lib = original_lib
...
# call some other test suite that actually needs the real thing
...
HTH。
编辑:稍微误解了您的问题,但是您可以检查MagicMock
对象以查看它们是否被调用,如果调用了,则测试失败。或者只是通过调用失败的东西修补(而不是MagicMock
)。如果需要,我可以提供执行此操作的代码(只需发表评论),但希望以上内容可以帮助您入门。我认为问题的症结在于真正的全球修补。干杯!