SlideShare a Scribd company logo
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.loads(raw)	
   不確定	
	
  	
  return	
  d['data']	
                                  確定的な	
  
                                 結果に依存
ユニットテストしにくい例	
•  戻り値が不確定	
  
  –  乱数	
  
  –  時刻	
  
•  セットアップがだるい	
  
  –  データベース	
  
  –  Web	
  API	
  
テスト対象の外側を入出力として扱う	

                               ここも入出力	
よびだし	
                                                 HTTP	
  req	
         def	
  foo(name):	
  
         	
  	
  raw	
  =	
  urlopen('http://…')	
  
         	
  	
  d	
  =	
  json.loads(raw)	
  
         	
  	
  return	
  d['data']	

戻り値	
                                                  HTTP	
  resp
そこで	
  mock	
  モジュール ですよ	
•  Python	
  3.2	
  以前 PyPI	
  
   –  easy_install,	
  pip,	
  etc.	
  


•  Python	
  3.3	
  標準ライブラリ	
  
   –  uniDest.mock	
  
1:	
  依存先オブジェクトを入れ替える	


テスト対象	
   urlopen	




テスト対象	
    mock
with	
  patch(...)	
  で入れ替える	
from	
  unittest.mock	
  import	
  patch	
  
def	
  test():	
  
	
  	
  with	
  patch('urllib.request.urlopen')	
  
	
  	
  as	
  m:	
  
	
  	
  	
  	
  result	
  =	
  foo('wozozo')	
  
Mock	
  オブジェクトと入れ替え	
>>>	
  with	
  patch('urllib.request.urlopen')	
  
	
  	
  	
  	
  as	
  m:	
  
...	
  	
  	
  from	
  urllib.request	
  import	
  urlopen	
  
...	
  	
  	
  urlopen	
  is	
  m	
  
...	
  	
  
True
Mock	
  オブジェクトはアクセスし放題	
>>>	
  m	
  
<MagicMock	
  name='urlopen'	
  id='1'>	
  
>>>	
  m.read()	
  
<MagicMock	
  name='urlopen.read()'	
  id='2'>	
  
>>>	
  m.hoge	
  
<MagicMock	
  name='urlopen.hoge'	
  id='3'>	
  
@patch	
  で入れ替える	
@patch('urllib.request.urlopen')	
  
def	
  test(m):	
  
	
  	
  result	
  =	
  foo('wozozo')	
  
setUp	
  と tearDown	
  で	
  patch	
class	
  MyTest(TestCase):	
  
	
  	
  def	
  setUp(self):	
  
	
  	
  	
  	
  self.patcher	
  =	
  patch('...')	
  
	
  	
  	
  	
  self.m	
  =	
  patcher.start()	
  
	
  
	
  	
  def	
  tearDown(self):	
  
	
  	
  	
  	
  self.patcher.stop()
2:	
  依存先の呼び出し履歴を確認	



テスト	
   テスト対象	
   mock
call_count	
  で呼び出し回数を確認	
@patch('urllib.request.urlopen')	
  
def	
  test(m):	
  
	
  	
  result	
  =	
  foo('wozozo')	
  
	
  	
  assert	
  m.call_count	
  ==	
  1	
  
call_args	
  で引数を確認	
@patch('urllib.request.urlopen')	
  
def	
  test(m):	
  
	
  	
  result	
  =	
  foo('wozozo')	
  
	
  	
  assert	
  m.call_count	
  ==	
  1	
  
	
  	
  assert	
  (m.call_args	
  ==	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (('http://...',),	
  {}))	
  
*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	
  =	
  json.loads(raw)	
  
	
  	
  return	
  d['data']
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	
  =	
  foo('wozozo')	
  
	
  	
  assert	
  m.call_count	
  ==	
  1	
  
	
  	
  assert	
  (m.call_args	
  ==	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (('http://…',),	
  {}))	
  
	
  	
  assert	
  result	
  ==	
  '…'	
  
複雑な戻り値は side_effect	
>>>	
  def	
  f(x,	
  y):	
  	
  
...	
  	
  	
  return	
  x	
  +	
  y	
  
...	
  	
  
>>>	
  m.side_effect	
  =	
  f	
  
>>>	
  m(1,	
  2)	
  
3
side_effect	
  に例外を指定	
>>>	
  m.side_effect	
  =	
  TypeError	
  
>>>	
  m()	
  
Traceback	
  (most	
  recent	
  call	
  last):	
  
...	
  
TypeError
mock	
  でユニットテストしやすくなる	



 テスト	
   テスト対象	
   mock
より詳しい話	
•  公式ドキュメント	
  
•  voluntas	
  「requests	
  と	
  mock	
  を使ってみる」	
  
     hDp://voluntas.hatenablog.com/entry/20111124/1322069748	
  
•  ぁっぉ 「mock	
  はこう使え」	
  
     hDp://d.hatena.ne.jp/atsuoishimoto/20120310/1331311730	
  

More Related Content

PDF
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
PDF
インフラチームのリモートワーク
PDF
ユーザー情報格納基盤におけるApache Pulsarの利用事例
PDF
Kubernetes にこれから入るかもしれない注目機能!(2022年11月版) / TechFeed Experts Night #7 〜 コンテナ技術を語る
PDF
Scapyで作る・解析するパケット
PPTX
NET Systems Programming Learned the Hard Way.pptx
PDF
AndroidアプリのKotlin移行時に遭遇した問題と対処例
PPTX
A developers guide to machine learning
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
インフラチームのリモートワーク
ユーザー情報格納基盤におけるApache Pulsarの利用事例
Kubernetes にこれから入るかもしれない注目機能!(2022年11月版) / TechFeed Experts Night #7 〜 コンテナ技術を語る
Scapyで作る・解析するパケット
NET Systems Programming Learned the Hard Way.pptx
AndroidアプリのKotlin移行時に遭遇した問題と対処例
A developers guide to machine learning

What's hot (8)

PDF
NGINX App Protect for Secure Coding Webinar
PPTX
VPP事始め
PDF
Apache Arrow - データ処理ツールの次世代プラットフォーム
PDF
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
PDF
Grafana Lokiの Docker Logging Driver入門 (Docker Meetup Tokyo #34, 2020/01/16)
PPTX
Guide: How to Build OpenCV 3.0.0
PDF
つくって壊して直して学ぶ Database on Kubernetes (CloudNative Days Summer 2025 発表資料)
PDF
100人100通りの働き方を支えるサイボウズ流情報システム部門の在り方
NGINX App Protect for Secure Coding Webinar
VPP事始め
Apache Arrow - データ処理ツールの次世代プラットフォーム
OpenStackで始めるクラウド環境構築入門(Horizon 基礎編)
Grafana Lokiの Docker Logging Driver入門 (Docker Meetup Tokyo #34, 2020/01/16)
Guide: How to Build OpenCV 3.0.0
つくって壊して直して学ぶ Database on Kubernetes (CloudNative Days Summer 2025 発表資料)
100人100通りの働き方を支えるサイボウズ流情報システム部門の在り方
Ad

Similar to Mock and patch (20)

PDF
Ekmett勉強会発表資料
PDF
Unit test in android
PPTX
Kompira開発者が教えるジョブフローTips7選_Kompass発表資料20240306.pptx
PDF
勉強会force#4 Chatter Integration
ODP
Ekmett勉強会発表資料
PDF
Pythonで始めるDropboxAPI
PDF
Ansible入門...?
PDF
Subprocess no susume
PDF
Pyramid入門
PDF
Swift 2.0 で変わったところ「後編」 #cswift
PDF
Ruby test double
KEY
Applicative functor
PDF
Local php-100828 2
PDF
ちょっと詳しくJavaScript 第2回【関数と引数】
PDF
研究生のためのC++ no.2
PDF
Continuation with Boost.Context
PDF
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
PPTX
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
KEY
Perl 非同期プログラミング
Ekmett勉強会発表資料
Unit test in android
Kompira開発者が教えるジョブフローTips7選_Kompass発表資料20240306.pptx
勉強会force#4 Chatter Integration
Ekmett勉強会発表資料
Pythonで始めるDropboxAPI
Ansible入門...?
Subprocess no susume
Pyramid入門
Swift 2.0 で変わったところ「後編」 #cswift
Ruby test double
Applicative functor
Local php-100828 2
ちょっと詳しくJavaScript 第2回【関数と引数】
研究生のためのC++ no.2
Continuation with Boost.Context
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
Perl 非同期プログラミング
Ad

More from Toru Furukawa (11)

PDF
Twitter 広告と API を組み合わせたインタラクティブなキャンペーン
PDF
My client wanted their apps synced, and I made it with Go
PPTX
Introduction to Python 3.4 as of beta 1
PDF
Test Failed, Then...
PDF
おまえらこのライブラリ使ってないの? m9 (2013-07)
PDF
Trying Continuous Delivery - pyconjp 2012
KEY
Python 3.3 チラ見
PDF
Python32 pyhackathon-201011
PDF
Django
PPTX
Python 2.7
PDF
BPStudy#34 導入
Twitter 広告と API を組み合わせたインタラクティブなキャンペーン
My client wanted their apps synced, and I made it with Go
Introduction to Python 3.4 as of beta 1
Test Failed, Then...
おまえらこのライブラリ使ってないの? m9 (2013-07)
Trying Continuous Delivery - pyconjp 2012
Python 3.3 チラ見
Python32 pyhackathon-201011
Django
Python 2.7
BPStudy#34 導入

Mock and patch