cno*_*ell 59 python testing unit-testing mocking nose
我有一个函数我要单元测试包含调用其他两个函数.我不确定如何使用补丁同时模拟两个函数.我在下面提供了一个我的意思的例子.当我运行测试时,测试通过,但我觉得必须有一个更清洁的方法来做到这一点,我真的不明白有关f.close()的部分...
目录结构如下所示:
program/
program/
data.py
tests/
data_test.py
Run Code Online (Sandbox Code Playgroud)
data.py:
import cPickle
def write_out(file_path, data):
f = open(file_path, 'wb')
cPickle.dump(data, f)
f.close()
Run Code Online (Sandbox Code Playgroud)
data_test.py:
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
mock_open = MagicMock()
mock_pickle = MagicMock()
f_mock = MagicMock()
with patch('__builtin__.open', mock_open):
f = mock_open.return_value
f.method.return_value = path
with patch('cPickle.dump', mock_pickle):
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
f.close.assert_any_call()
mock_pickle.assert_called_once_with('data', f)
Run Code Online (Sandbox Code Playgroud)
结果:
$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
Run Code Online (Sandbox Code Playgroud)
Mat*_*ohn 90
您可以使用修补程序装饰器简化测试并将它们嵌套(MagicMock
默认情况下它们是对象):
@patch('cPickle.dump')
@patch('__builtin__.open')
def test_write_out(mock_open, mock_pickle):
path = '~/collection'
f = mock_open.return_value
f.method.return_value = path
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
mock_pickle.assert_called_once_with('data', f)
f.close.assert_any_call()
Run Code Online (Sandbox Code Playgroud)
对MagicMock
实例的调用返回一个新MagicMock
实例,因此您可以检查返回的值是否像任何其他模拟对象一样被调用.在这种情况下f
是一个MagicMock
命名'open()'
(尝试打印f
).
Ale*_*voy 39
除了响应@Matti John之外,您还可以使用patch
内部函数test_write_out
:
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
with patch('__builtin__.open') as mock_open, \
patch('cPickle.dump') as mock_pickle:
f = mock_open.return_value
...
Run Code Online (Sandbox Code Playgroud)
Mar*_*arc 16
从 Python 3.10 开始,您可以像这样使用带括号的上下文管理器
from unittest.mock import patch
def test_write_out():
with (
patch('cPickle.dump'),
patch('__builtin__.open') as open_mock, # example of using `as`
):
yield
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
45082 次 |
最近记录: |