MagicMock return 基于输入的值
MagicMock return value based on input
我正在尝试将我的测试从 flexmock 重构为 mock。给出来自 flexmock 的以下语法:
flexmock(subprocess).should_receive('check_output').with_args('ls /').and_return(output)
如何使用 Mock 重写它?特别是,如何使用 Mock 将 return 值固定到特定输入?
您可以使用 side_effect
patch
属性来完成:
>>> from unittest.mock import *
>>> root = '''bin cdrom etc initrd.img lib32 libx32 media opt root sbin sys usr vmlinuz
... boot dev home lib lib64 lost+found mnt proc run srv tmp var'''
>>> answer = {'ls /': root}
>>> import subprocess
>>> with patch('subprocess.check_output', side_effect=lambda arg, *args, **kwargs: answer[arg]) as mock_check_output :
... assert root == subprocess.check_output('ls /')
... mock_check_output.assert_called_with('ls /')
... subprocess.check_output('something else')
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "/usr/lib/python3.4/unittest/mock.py", line 896, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/usr/lib/python3.4/unittest/mock.py", line 962, in _mock_call
ret_val = effect(*args, **kwargs)
File "<stdin>", line 1, in <lambda>
KeyError: 'something else'
>>>
我很确定你会发现它比 flexmock
的语法更难一些,但你需要的是存根而不是模拟。如果您可以将测试设计为隔离并在某个设置阶段配置 mock/stub,您可能会发现这种语法很好,并且所有 mock
断言和 patch
选项都非常强大。
我正在尝试将我的测试从 flexmock 重构为 mock。给出来自 flexmock 的以下语法:
flexmock(subprocess).should_receive('check_output').with_args('ls /').and_return(output)
如何使用 Mock 重写它?特别是,如何使用 Mock 将 return 值固定到特定输入?
您可以使用 side_effect
patch
属性来完成:
>>> from unittest.mock import *
>>> root = '''bin cdrom etc initrd.img lib32 libx32 media opt root sbin sys usr vmlinuz
... boot dev home lib lib64 lost+found mnt proc run srv tmp var'''
>>> answer = {'ls /': root}
>>> import subprocess
>>> with patch('subprocess.check_output', side_effect=lambda arg, *args, **kwargs: answer[arg]) as mock_check_output :
... assert root == subprocess.check_output('ls /')
... mock_check_output.assert_called_with('ls /')
... subprocess.check_output('something else')
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "/usr/lib/python3.4/unittest/mock.py", line 896, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/usr/lib/python3.4/unittest/mock.py", line 962, in _mock_call
ret_val = effect(*args, **kwargs)
File "<stdin>", line 1, in <lambda>
KeyError: 'something else'
>>>
我很确定你会发现它比 flexmock
的语法更难一些,但你需要的是存根而不是模拟。如果您可以将测试设计为隔离并在某个设置阶段配置 mock/stub,您可能会发现这种语法很好,并且所有 mock
断言和 patch
选项都非常强大。