minimockã®ä½¿ãæ¹
pythonã®ã¢ãã¯ã¨ãã¦minimockã¨ããã©ã¤ãã©ãªãããã
æ¥æ¬èªã®ããã¥ã¡ã³ãã»ããã°ãè¦å½ãããªãã®ã§ä½¿ãæ¹ãããã«æ¸ãã¦ããã
minimockãæ§æããã¢ã¸ã¥ã¼ã«
- mocké¢æ° -- ã¢ãã¯ãå½ã¦ãã
- restoreé¢æ° -- å½ã¦ãã¢ãã¯ã解é¤ããã
- Mockã¯ã©ã¹ -- mockãã詳細ã«ã¢ãã¯ãå½ã¦ãããã«ä½¿ããªãã¸ã§ã¯ãã
mocké¢æ°ã¨restoreé¢æ°ã§ã¢ãã¯ãå½ã¦ãã»è§£é¤ããã¨ããã®ã¯ããããããã
ããããè¤éãªã±ã¼ã¹ã§ã¯Mockãªãã¸ã§ã¯ãã使ãå¿
è¦ãããã®ã§ããã§èª¬æããã
ãã¨ãminimockã使ãä¸ã§ã¯ã¾ããããç¹ãæ¸ãã
åºæ¬çãªä½¿ãæ¹
minimockã®åºæ¬ã¯
- ã¢ãã¯ã«å·®ãæ¿ããã¢ã¸ã¥ã¼ã«ãã¤ã³ãã¼ãããã
- mocké¢æ°ãå¼ã¶ãæãã¯Mockã¤ã³ã¹ã¿ã³ã¹ãä»£å ¥ããã
- 使ãçµãã£ããrestoreã§æ»ãã
ã§ããã
ä¾ãã°ã以ä¸ã®philosophyã¨ããã¢ã¸ã¥ã¼ã«ã®ãã¹ããæ¸ãã¨ãããã
[philosophy.py]
# -*- coding:utf-8 -*- import urllib def soccer(num): url = r'http://en.wikipedia.org/w/index.php?title=Monty_Python%%27s_Flying_Circus&limit=%s&action=history' archimedes = urllib.urlopen(url % num) print '!!! eureka !!!', archimedes and archimedes.headers.dict['content-length'] return 2 * num
philosophyã¯urllibã¢ã¸ã¥ã¼ã«ã使ã£ã¦URLã®åãåãããè¡ã£ã¦ãã¾ãã®ã§ããã®é¨åãã¢ãã¯ã«å·®ãæ¿ãããã
ããããå ´åã以ä¸ã®éãããã¨URLã®åãåãããåé¿ã§ããã
[test_philosophy.py]
# -*- coding:utf-8 -*- import unittest from minimock import mock, Mock, restore import philosophy class PhilosophyTest(unittest.TestCase): def setUp(self): import urllib mock('urllib.urlopen') def tearDown(self): restore() def test(self): self.assertEquals(philosophy.soccer(1), 2) if __name__ == '__main__': unittest.main()
使ç¨ä¸ã®æ³¨æ -- 対象ã®ãªãã¸ã§ã¯ããçã£ã¦ã¢ãã¯ãé©ç¨ããã
minimockã使ãã¨ãã注æããªããã°ãããªããã¨ãä¸ã¤ããã
ããã¯ãã¢ãã¯ã«å·®ãæ¿ãããªãã¸ã§ã¯ããã¡ããã¨çãæã¡ããããã£ã¦ãã¨ã ã
ä¾ãã°ãphilosophyã¨åããããªspanishã¨ããã¢ã¸ã¥ã¼ã«ã®ãã¹ããæ¸ããã¨ããã
[spanish.py]
# -*- coding:utf-8 -*- from urllib import urlopen def inquisition(num): url = r'http://en.wikipedia.org/w/index.php?title=The_Spanish_Inquisition_(Monty_Python)&limit=%s&action=history' cardinal_fang = urlopen(url % num) print '=== the result ===', cardinal_fang and cardinal_fang.headers.dict['content-length'] return 2 * num
spanishã®ãããã¬ãã«ã§urllibã§ã¯ãªããurlopenãfromã¤ã³ãã¼ããã¦ããæã«æ³¨æã ã
philosophyã®è¦é ã§ä»åº¦ã
class SpanishInquisitionTest(unittest.TestCase): def setUp(self): import urllib mock('urllib.urlopen')
ãããªé¢¨ã«æ¸ãã¦ãã¾ãã¨ã¢ãã¯ã«ãªãããURLã®åãåãããå®éã«è¡ããã¦ãã¾ãã
fromã¤ã³ãã¼ãããã¨ãªãã¸ã§ã¯ããã³ãã¼ããã¦ãã¾ãã®ã§ããã®å ´åã¯urllib.urlopenã§ã¯ãªãã¦spanish.urlopenãçãæã¡ããªããã°ãªããªãã®ã ã
以ä¸ã®éãã«ããã¨ã¡ããã¨urlopenã®å¦çãæ½°ããã
(mocké¢æ°ã ã¨ãã¾ããããªãã£ãã®ã§ãMockã¤ã³ã¹ã¿ã³ã¹ã代å
¥ãã¦å¯¾å¦)
[test_spanish.py]
# -*- coding:utf-8 -*- import unittest from minimock import mock, Mock, restore import spanish class SpanishInquisitionTest(unittest.TestCase): def setUp(self): spanish.urlopen = Mock('spanish.urlopen') mock('spanish.urlopen') def tearDown(self): restore() def test(self): self.assertEquals(spanish.inquisition(7), 14) if __name__ == '__main__': unittest.main()
ã¢ãã¯ã«ããã¼ã®å¤ãè¿æ»ããããã¨ã -- returnsã使ã
mocké¢æ°ã®å¼ã³åºãã«returnsã¨ããå¼æ°ãåããã®ã§ããã使ãã
ä¾ãã°ãurllib2.bulid_openerãè¿ããopenerã使ã£ã¦åãåãããè¡ãå ´åãMockãªãã¸ã§ã¯ãã使ã£ã¦ä»¥ä¸ã®ããã«ã§ããã
[alength.py]
# -*- coding:utf-8 -*- import urllib2 def get_length(): handler = urllib2.HTTPBasicAuthHandler() handler.add_password('Title', 'akakakakakakak.com', 'akst', 'heatup') opener = urllib2.build_opener(handler) res = opener.open('http://akakakakakakak.com?heatup=1') return len(res.read()) #=> 'f' * 555
[test_a.py]
from minimock import mock, Mock, restore
import unittest
import alength
from StringIO import StringIO
class ALengthTest(unittest.TestCase):
def setUp(self):
alength.urllib2.build_opener = Mock('build_opener', \
returns=Mock('opener',\
open=Mock('opener.open', returns=StringIO('f'*555))))
def tearDown(self):
restore()
def test(self):
self.assertEquals(alength.get_length(), 555)
if __name__ == '__main__':
unittest.main()
Mockã®ã³ã³ã¹ãã©ã¯ã¿ã«ã¯ä»»æã®ååã®å±æ§ãæå®ã§ããã
ä»åã¯openerã®ã¢ãã¯ã®openã«æ´ã«Mockãè¿ãããå®ç¾©ããã
ç¶æ³ã«ãã£ã¦ã¢ãã¯ãè¿ãå¤ãå¤ãããã¨ã -- returns_funcã®ä½¿ãæ¹
Mockã®ã³ã³ã¹ãã©ã¯ã¿ã«ã¯returns_funcã¨ããå¼æ°ã渡ããã
ããã使ãã¨ãcallableãªå±æ§ãcallableãªã¢ãã¯ã§ç½®ãæããããã
ä¾ãã°ããã£ãã®build_openerã®ä¾ã§opener.openã3åå¼ã³åºãã¦ãããããè¿ãå¤ãå¤ãã¦ãã¹ããããå ´åãªã©ã«ä½¿ãã¨è¯ãã
def setUp(self): files = [ StringIO(x) for x in ['f' * 555, 'm' * 432, 'h' * 156]] alength.urllib2.build_opener = Mock('build_opener', returns=Mock('opener', open=Mock('opener.open', returns_func=lambda *args, **kwargs: files.pop(0))))
ã¨ã«ããå¼ã¹ãã°ããã®ã§å¼æ°ã*args, **kwargsã®lambdaã«ããã
ä¸è¨ã³ã¼ãã«ããã¨ãbuild_openerãè¿ããªãã¸ã§ã¯ãã®openãfiles.pop(0)ãå
ãã§ããlambdaã«ç½®ãæããã
ã¤ã¾ããopenãå¼ã¶ã¨filesã®ãªã¹ãããå
é è¦ç´ ãåãåºãã¦è¿ãããã«ãªãã®ã§ãå¼ã¶ãã³ã«æ»ãå¤ãå¤ããã