MagicMock возвращает значение на основе ввода

Я пытаюсь реорганизовать свои тесты с flexmock на mock. Учитывая следующий синтаксис из flexmock:

flexmock(subprocess).should_receive('check_output').with_args('ls /').and_return(output)

Как я могу переписать это с помощью Mock? В частности, как с помощью Mock привязать возвращаемое значение к определенному вводу?


person Jon Skarpeteig    schedule 17.11.2015    source источник


Ответы (1)


Вы можете использовать атрибут 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 утверждения и patch опции очень мощными.

person Michele d'Amico    schedule 18.11.2015