Mock	  と	  patch	 ふるかわとおる
お前、誰よ?	•  ふるかわとおる	    –  @torufurukawa	    –  bucho	  と呼ばれています	  •  株式会社バスキュール	    –  生放送テレビ番組と連動するサービス	    –  エンジニア足りません	  
ユニットテスト	def	  test():	  	  	  result	  =	  foo(wozozo)	  	  	  assert	  result	  ==	  unko	  
依存先…	def	  foo(name):	  	  	  f	  =	  urlopen(http://%s.com/	  %	  name)	  	  	  raw	  =	  f.read()	  	  	  d	  =	  json.l...
ユニットテストしにくい例	•  戻り値が不確定	    –  乱数	    –  時刻	  •  セットアップがだるい	    –  データベース	    –  Web	  API	  
テスト対象の外側を入出力として扱う	                               ここも入出力	よびだし	                                                 HTTP	  req	 ...
そこで	  mock	  モジュール ですよ	•  Python	  3.2	  以前 PyPI	     –  easy_install,	  pip,	  etc.	  •  Python	  3.3	  標準ライブラリ	     –  u...
1:	  依存先オブジェクトを入れ替える	テスト対象	   urlopen	テスト対象	    mock
with	  patch(...)	  で入れ替える	from	  unittest.mock	  import	  patch	  def	  test():	  	  	  with	  patch(urllib.request.urlop...
Mock	  オブジェクトと入れ替え	>>>	  with	  patch(urllib.request.urlopen)	  	  	  	  	  as	  m:	  ...	  	  	  from	  urllib.request	  ...
Mock	  オブジェクトはアクセスし放題	>>>	  m	  <MagicMock	  name=urlopen	  id=1>	  >>>	  m.read()	  <MagicMock	  name=urlopen.read()	  id...
@patch	  で入れ替える	@patch(urllib.request.urlopen)	  def	  test(m):	  	  	  result	  =	  foo(wozozo)	  
setUp	  と tearDown	  で	  patch	class	  MyTest(TestCase):	  	  	  def	  setUp(self):	  	  	  	  	  self.patcher	  =	  patch...
2:	  依存先の呼び出し履歴を確認	テスト	   テスト対象	   mock
call_count	  で呼び出し回数を確認	@patch(urllib.request.urlopen)	  def	  test(m):	  	  	  result	  =	  foo(wozozo)	  	  	  assert	  ...
call_args	  で引数を確認	@patch(urllib.request.urlopen)	  def	  test(m):	  	  	  result	  =	  foo(wozozo)	  	  	  assert	  m.cal...
*args	  と	  **kw	  が返ってくる	m(a,	  b,	  x=1)	  ↓	  m.call_args	  ==	  ((a,	  b),	  {x:	  1})
3:	  依存先の挙動を定義する	テスト	   テスト対象	   mock
return_value	  で戻り値定義	>>>	  m.return_value	  =	  999	  >>>	  m()	  999	  
urlopen().read()	def	  foo(name):	  	  	  f	  =	  urlopen(http://%s.com/	  %	  name)	  	  	  raw	  =	  f.read()	  	  	  d	...
return_value	  で戻り値定義	>>>	  m.return_value.meth.return_value	  =	  1	  >>>	  m().meth()	  1	  
@patch(urllib.request.urlopen)	  def	  test_foo(m):	  	  	  m.return_value.read.return_value	  =	  …	  	  	  result	  =	  ...
複雑な戻り値は side_effect	>>>	  def	  f(x,	  y):	  	  ...	  	  	  return	  x	  +	  y	  ...	  	  >>>	  m.side_effect	  =	  f	  >>>...
side_effect	  に例外を指定	>>>	  m.side_effect	  =	  TypeError	  >>>	  m()	  Traceback	  (most	  recent	  call	  last):	  ...	  T...
mock	  でユニットテストしやすくなる	 テスト	   テスト対象	   mock
より詳しい話	•  公式ドキュメント	  •  voluntas	  「requests	  と	  mock	  を使ってみる」	       hDp://voluntas.hatenablog.com/entry/20111124/1322...
Upcoming SlideShare
Loading in...5
×

Mock and patch

1,514

Published on

Python mock ライブラリの紹介

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,514
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
10
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Mock and patch

  1. 1. Mock  と  patch ふるかわとおる
  2. 2. お前、誰よ? •  ふるかわとおる   –  @torufurukawa   –  bucho  と呼ばれています  •  株式会社バスキュール   –  生放送テレビ番組と連動するサービス   –  エンジニア足りません  
  3. 3. ユニットテスト def  test():      result  =  foo(wozozo)      assert  result  ==  unko  
  4. 4. 依存先… def  foo(name):      f  =  urlopen(http://%s.com/  %  name)      raw  =  f.read()      d  =  json.loads(raw)   不確定    return  d[data] 確定的な   結果に依存
  5. 5. ユニットテストしにくい例 •  戻り値が不確定   –  乱数   –  時刻  •  セットアップがだるい   –  データベース   –  Web  API  
  6. 6. テスト対象の外側を入出力として扱う ここも入出力 よびだし HTTP  req def  foo(name):      raw  =  urlopen(http://…)      d  =  json.loads(raw)      return  d[data] 戻り値 HTTP  resp
  7. 7. そこで  mock  モジュール ですよ •  Python  3.2  以前 PyPI   –  easy_install,  pip,  etc.  •  Python  3.3  標準ライブラリ   –  uniDest.mock  
  8. 8. 1:  依存先オブジェクトを入れ替える テスト対象 urlopen テスト対象 mock
  9. 9. with  patch(...)  で入れ替える from  unittest.mock  import  patch  def  test():      with  patch(urllib.request.urlopen)      as  m:          result  =  foo(wozozo)  
  10. 10. Mock  オブジェクトと入れ替え >>>  with  patch(urllib.request.urlopen)          as  m:  ...      from  urllib.request  import  urlopen  ...      urlopen  is  m  ...    True
  11. 11. Mock  オブジェクトはアクセスし放題 >>>  m  <MagicMock  name=urlopen  id=1>  >>>  m.read()  <MagicMock  name=urlopen.read()  id=2>  >>>  m.hoge  <MagicMock  name=urlopen.hoge  id=3>  
  12. 12. @patch  で入れ替える @patch(urllib.request.urlopen)  def  test(m):      result  =  foo(wozozo)  
  13. 13. setUp  と tearDown  で  patch class  MyTest(TestCase):      def  setUp(self):          self.patcher  =  patch(...)          self.m  =  patcher.start()        def  tearDown(self):          self.patcher.stop()
  14. 14. 2:  依存先の呼び出し履歴を確認 テスト テスト対象 mock
  15. 15. call_count  で呼び出し回数を確認 @patch(urllib.request.urlopen)  def  test(m):      result  =  foo(wozozo)      assert  m.call_count  ==  1  
  16. 16. call_args  で引数を確認 @patch(urllib.request.urlopen)  def  test(m):      result  =  foo(wozozo)      assert  m.call_count  ==  1      assert  (m.call_args  ==                      ((http://...,),  {}))  
  17. 17. *args  と  **kw  が返ってくる m(a,  b,  x=1)  ↓  m.call_args  ==  ((a,  b),  {x:  1})
  18. 18. 3:  依存先の挙動を定義する テスト テスト対象 mock
  19. 19. return_value  で戻り値定義 >>>  m.return_value  =  999  >>>  m()  999  
  20. 20. urlopen().read() def  foo(name):      f  =  urlopen(http://%s.com/  %  name)      raw  =  f.read()      d  =  json.loads(raw)      return  d[data]
  21. 21. return_value  で戻り値定義 >>>  m.return_value.meth.return_value  =  1  >>>  m().meth()  1  
  22. 22. @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  ==  …  
  23. 23. 複雑な戻り値は side_effect >>>  def  f(x,  y):    ...      return  x  +  y  ...    >>>  m.side_effect  =  f  >>>  m(1,  2)  3
  24. 24. side_effect  に例外を指定 >>>  m.side_effect  =  TypeError  >>>  m()  Traceback  (most  recent  call  last):  ...  TypeError
  25. 25. mock  でユニットテストしやすくなる テスト テスト対象 mock
  26. 26. より詳しい話 •  公式ドキュメント  •  voluntas  「requests  と  mock  を使ってみる」   hDp://voluntas.hatenablog.com/entry/20111124/1322069748  •  ぁっぉ 「mock  はこう使え」   hDp://d.hatena.ne.jp/atsuoishimoto/20120310/1331311730  
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×