+ All Categories
Home > Technology > Mock and patch

Mock and patch

Date post: 25-Jun-2015
Category:
Upload: toru-furukawa
View: 1,459 times
Download: 0 times
Share this document with a friend
Description:
Python mock ライブラリの紹介
Popular Tags:
26
Mock patch ふるかわとおる
Transcript
Page 1: Mock and patch

Mock  と  patch

ふるかわとおる

Page 2: Mock and patch

お前、誰よ?

•  ふるかわとおる  – @torufurukawa  – bucho  と呼ばれています  

•  株式会社バスキュール  – 生放送テレビ番組と連動するサービス  – エンジニア足りません  

Page 3: Mock and patch

ユニットテスト

def  test():      result  =  foo('wozozo')      assert  result  ==  'unko'  

Page 4: Mock and patch

依存先…

def  foo(name):      f  =  urlopen('http://%s.com/'  %  name)      raw  =  f.read()      d  =  json.loads(raw)      return  d['data']

不確定

確定的な  結果に依存

Page 5: Mock and patch

ユニットテストしにくい例

•  戻り値が不確定  – 乱数  – 時刻  

•  セットアップがだるい  – データベース  – Web  API  

Page 6: Mock and patch

テスト対象の外側を入出力として扱う

def  foo(name):      raw  =  urlopen('http://…')      d  =  json.loads(raw)      return  d['data']

よびだし HTTP  req

HTTP  resp 戻り値

ここも入出力

Page 7: Mock and patch

そこで  mock  モジュール ですよ

•  Python  3.2  以前 PyPI  – easy_install,  pip,  etc.  

•  Python  3.3  標準ライブラリ  – uniDest.mock  

Page 8: Mock and patch

1:  依存先オブジェクトを入れ替える

テスト対象 urlopen

テスト対象 mock

Page 9: Mock and patch

with  patch(...)  で入れ替える

from  unittest.mock  import  patch  def  test():      with  patch('urllib.request.urlopen')\      as  m:          result  =  foo('wozozo')  

Page 10: Mock and patch

Mock  オブジェクトと入れ替え

>>>  with  patch('urllib.request.urlopen')\          as  m:  ...      from  urllib.request  import  urlopen  ...      urlopen  is  m  ...    True

Page 11: Mock and patch

Mock  オブジェクトはアクセスし放題

>>>  m  <MagicMock  name='urlopen'  id='1'>  >>>  m.read()  <MagicMock  name='urlopen.read()'  id='2'>  >>>  m.hoge  <MagicMock  name='urlopen.hoge'  id='3'>  

Page 12: Mock and patch

@patch  で入れ替える

@patch('urllib.request.urlopen')  def  test(m):      result  =  foo('wozozo')  

Page 13: Mock and patch

setUp  と tearDown  で  patch

class  MyTest(TestCase):      def  setUp(self):          self.patcher  =  patch('...')          self.m  =  patcher.start()        def  tearDown(self):          self.patcher.stop()

Page 14: Mock and patch

2:  依存先の呼び出し履歴を確認

テスト対象 mock テスト

Page 15: Mock and patch

call_count  で呼び出し回数を確認

@patch('urllib.request.urlopen')  def  test(m):      result  =  foo('wozozo')      assert  m.call_count  ==  1  

Page 16: Mock and patch

call_args  で引数を確認

@patch('urllib.request.urlopen')  def  test(m):      result  =  foo('wozozo')      assert  m.call_count  ==  1      assert  (m.call_args  ==                      (('http://...',),  {}))  

Page 17: Mock and patch

*args  と  **kw  が返ってくる

m(a,  b,  x=1)  ↓  m.call_args  ==  ((a,  b),  {'x':  1})

Page 18: Mock and patch

3:  依存先の挙動を定義する

テスト対象 mock テスト

Page 19: Mock and patch

return_value  で戻り値定義

>>>  m.return_value  =  999  >>>  m()  999  

Page 20: Mock and patch

urlopen().read()

def  foo(name):      f  =  urlopen('http://%s.com/'  %  name)      raw  =  f.read()      d  =  json.loads(raw)      return  d['data']

Page 21: Mock and patch

return_value  で戻り値定義

>>>  m.return_value.meth.return_value  =  1  >>>  m().meth()  1  

Page 22: Mock and patch

@patch('urllib.request.urlopen')  def  test_foo(m):      m.return_value.read.return_value  =  '…'      result  =  foo('wozozo')      assert  m.call_count  ==  1      assert  (m.call_args  ==                      (('http://…',),  {}))      assert  result  ==  '…'  

Page 23: Mock and patch

複雑な戻り値は side_effect

>>>  def  f(x,  y):    ...      return  x  +  y  ...    >>>  m.side_effect  =  f  >>>  m(1,  2)  3

Page 24: Mock and patch

side_effect  に例外を指定

>>>  m.side_effect  =  TypeError  >>>  m()  Traceback  (most  recent  call  last):  ...  TypeError

Page 25: Mock and patch

テスト対象 mock テスト

mock  でユニットテストしやすくなる

Page 26: Mock and patch

より詳しい話

•  公式ドキュメント  •  voluntas  「requests  と  mock  を使ってみる」  

hDp://voluntas.hatenablog.com/entry/20111124/1322069748  

•  ぁっぉ 「mock  はこう使え」  hDp://d.hatena.ne.jp/atsuoishimoto/20120310/1331311730  


Recommended