vij*_*ker 2 python unit-testing mocking
我有一个文件 copy_x_to_y.py ,如下所示:
from abcd import F
def function_to_be_tested():
F()
Run Code Online (Sandbox Code Playgroud)
在 abcd.py 文件中,我有这样的内容:
from xyz import XY
class F():
def __init__(self, arg1):
self.xy = XY(arg1)
Run Code Online (Sandbox Code Playgroud)
我想在我的测试用例中模拟 XY 的init 。我尝试用以下方法来模拟 F 的 init:
def mock_func(*args, **kwargs):
pass
@patch('path/to/copy_x_to_y.F.__init__', mock_func)
def test():
assert function_to_be_tested() is None
Run Code Online (Sandbox Code Playgroud)
但它总是会调用 XY 的 init,导致错误,因为它的初始化调用通过 arg1 与 S3 连接。如何测试这种结构?
小智 5
__init__想要嘲笑的理由是什么XY?您是否希望它返回 XY 的特定对象,是否想检查是否XY.__init__使用特定参数或其他内容调用?
解决您的问题的一个可能的解决方案是模拟整个类,但让它返回一个“正常”对象。这是一个例子:
>>> from unittest.mock import patch
>>> class MyClass:
... def __init__(self, val):
... self._val = val
... def foo(self):
... print(self._val)
...
>>> a = MyClass(1)
>>> a.foo()
1
>>> patcher = patch('__main__.MyClass', return_value=a)
>>> mock_class = patcher.start()
>>> b = MyClass(2) # This will return a.
>>> b.foo()
1
>>> mock_class.call_args_list
[call(2)]
>>> patcher.stop()
Run Code Online (Sandbox Code Playgroud)
在你的情况下是:
from xyz import XY
from path/to/copy_x_to_y import function_to_be_tested
def test():
arg1 = ...
a = XY(arg1) # Has to be called before the patch to get a "normal" object.
with patch('xyz.XY', return_value=a) as mock_xy:
# Run funcion to be tested here and check results.
function_to_be_tested()
assert ...
Run Code Online (Sandbox Code Playgroud)
__init__如果您确实需要这样做,则可以直接模拟。>>> def my_init(self, *args, **kwargs):
... self._val = 1
>>> patcher = patch.object(MyClass, '__init__', my_init)
>>> mock_init = patcher.start()
>>> a = MyClass(2)
>>> a.foo()
1
Run Code Online (Sandbox Code Playgroud)
@patch('path/to/SomeClass', ...)
def test(mock_class):
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4302 次 |
| 最近记录: |