Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@FGtatsuro
Last active August 25, 2018 11:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FGtatsuro/11542313 to your computer and use it in GitHub Desktop.
Save FGtatsuro/11542313 to your computer and use it in GitHub Desktop.
mock(Pythonモックライブラリ)についてのメモ ref: https://qiita.com/FGtatsuro/items/eea263bc15ebfb9767cd
class A(object):
def a_test(self):
print('test')
class B(object):
def __init__(self, a_ins):
self.a_ins = a_ins
def b_test(self):
return self.a_ins.a_test()
# このプレフィックスを持つメソッドに対してのみ、モックが渡される。
>>> patch.TEST_PREFIX
'test'
>>> @patch('__main__.C')
class CTest(object):
def test_c(self, CMock):
c = CMock()
c.hoge.return_value = 'hoge_test'
print(c.hoge())
def notmock(self, CMock):
pass
...
# 'test'で始まるメソッド。モックが渡される。
>>> CTest().test_c()
hoge_test
# 'test'で始まらないメソッド。モックが渡されないため、引数不足でエラーになる。
>>> CTest().notmock()
Traceback (most recent call last):
File "<ipython-input-189-cee8cb83c7b4>", line 1, in <module>
CTest().notmock()
TypeError: notmock() missing 1 required positional argument: 'CMock'
>>> class C(object):
def hoge(self):
return 'hoge'
# withステートメント下のスコープのみで、クラスCのモック(CMock)を使用可能
>>> with patch('__main__.C') as CMock:
c = CMock()
c.hoge.return_value = 'test'
print(c.hoge())
...
test
>>> @patch('__main__.C')
def patched_func(CMock):
c = CMock()
c.hoge.return_value = 'test'
print(c.hoge())
...
>>> patched_func()
test
>>> a = Mock(spec=A)
>>> a.a_test.side_effect = ValueError
>>> b = B(a)
>>> b.b_test()
error handling
>>> a = A()
>>> a.a_test = Mock()
>>> a.a_test.return_value = 'mocked'
>>> b = B(a)
>>> b.b_test()
'mocked'
>>> a = Mock(spec=A)
>>> a.a_test.return_value = 'mocked_spec'
>>> b = B(a)
>>> b.b_test()
'mocked_spec'
>>> a = Mock(spec=A)
>>> a.a_test.return_value = 'mocked_spec'
>>> b = B(a)
# Mock#call_args_list:該当するMockインスタンスの呼び出しを保存するリスト
>>> a.a_test.call_args_list
[]
# Mock#assert_any_call:該当するMockインスタンス呼び出しが過去にあったかをassertする。
# 今回の例では引数なしだが、実際には任意の引数を与えることが可能(その引数を与えたMockインスタンス呼び出しがあったかをassertする)
# (ref. http://www.voidspace.org.uk/python/mock/mock.html)
>>> a.a_test.assert_any_call()
Traceback (most recent call last):
File "<ipython-input-81-ed526bd5ddf7>", line 1, in <module>
a.a_test.assert_any_call()
File "/Users/tatsuro/.venv/py3.3/lib/python3.3/site-packages/mock.py", line 891, in assert_any_call
'%s call not found' % expected_string
AssertionError: a_test() call not found
>>> b.b_test()
'mocked_spec'
# B#b_test()経由で呼び出されている
>>> a.a_test.call_args_list
[call()]
>>> a.a_test.assert_any_call()
>>>
class A(object):
def a_test(self):
raise ValueError
class B(object):
def __init__(self, a_ins):
self.a_ins = a_ins
def b_test(self):
try:
return self.a_ins.a_test()
except ValueError:
print('error handling')
>>> class B(object):
def __init__(self, a_ins):
self.a_ins = a_ins
def b_test(self, value):
try:
return self.a_ins.a_test(value)
except ValueError:
print('error handling')
>>> def handler(value):
if (value % 2) == 0:
return value * 2
return value
>>> a.a_test.side_effect = handler
>>> b = B(a)
>>> b.b_test(1)
1
>>> b.b_test(2)
4
>>> b.b_test(3)
3
>>> from mock import Mock
>>> m = Mock()
# return_value属性に戻り値をセット
>>> m.return_value = 5
>>> m()
5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment