??????????????? Python ?? Mock ????á?
?????????е?????????????????????
???????????????д??????????????Щ??????“????”??????????????????????????????????ó?????????????????????????????????????Щ??????????????????“?????”????????????????е????????????磺????????д????罻 app???????????????? "?????? Facebook" ???1?????????????????в????????????????? Facebook??
????Python ?? unittest ????????????? unittest.mock ????????????????????????? mock —— ????????????????????????????????? ??? mock ???????Щ??????????????á?
??????? mock ??????? ???? Python 3.3 ???????У??????????汾??????? PyPI ???? Mock ??
?????????????
????????????????????????????????????????????????? ?????? ????????????Щ????????????????????????????????д?????????? CD ?????????????????????????? /tmp ?1???????????? Web ??????????????? TCP ???? socket ??????????Щ?????????????????????????в??????????????á?
?????????????????????????????????????????????????????? CD ?????????????????????????????????????????? CD ??????????????е???????????????????????????????Σ??????????????????????????????????????????
????????????????????Ч?????????ζ????????????“????????”??????????????????????????????
???????????????????????????????????????? mock ????????? Python ???????????????????????? mock д??????????????????????????????????????????????????????????????
??????????????????
??????????й????????????????????????????????????????????? Python ??д????????????????????????????????????
????#!/usr/bin/env python
????# -*- coding: utf-8 -*-
????import os
????def rm(filename):
????os.remove(filename)
???????????????? rm ?????????????? os.remove ??????????????????????????????????????????????????????????????
??????????д??????????????????????????? mock ??
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import rm
import os.path
import tempfile
import unittest
class RmTestCase(unittest.TestCase):
tmpfilepath = os.path.join(tempfile.gettempdir()?? "tmp-testfile")
def setUp(self):
with open(self.tmpfilepath?? "wb") as f:
f.write("Delete me!")
def test_rm(self):
# remove the file
rm(self.tmpfilepath)
# test that it was actually removed
self.assertFalse(os.path.isfile(self.tmpfilepath)?? "Failed to remove the file.")
????????????????????????????????????е???????????????????????????????????????????а?????????? rm ????????????????????????′???? os.remove ???á??????????????????? ??? ??????????????к??????????????
??????? Mock ???
????????????? mock ?????????????????
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import rm
import mock
import unittest
class RmTestCase(unittest.TestCase):
@mock.patch('mymodule.os')
def test_rm(self?? mock_os):
rm("any path")
# test that rm called os.remove with the right parameters
mock_os.remove.assert_called_with("any path")
?????????Щ?????????????????????????????????????????????????????????????????????????????
???????????
???????????????????????????????? mock.patch ??????????????????λ?? mymodule.os ?????????? mock ?????????????????????????????? os ??????????? mymodule.os ?? os ???????LCTT ???????? @mock.patch('mymodule.os') ??????? mymodule.os ?μ? os ??????????????????
????????????漰????????????飬Python ???÷??????????????????? mymodule ??????????????????????????????? os ???????????????? os ????????????? mock ?? mymodule ????е??????????
??????仰???????????
???????????????????????δ?????????????????
????????????? myproject.app.MyElaborateClass ??? tempfile ??飬?????????? mock ???? myproject.app.tempfile ??????????鱣??????????
???????????????????????????????
?????? ‘rm’ ?м??????
??????????? rm ????????????????????????????????????????·?????????????????????????????????????? rm ?????????????
????#!/usr/bin/env python
????# -*- coding: utf-8 -*-
????import os
????import os.path
????def rm(filename):
????if os.path.isfile(filename):
????os.remove(filename)
??????á???????????????????????????????????????
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import rm
import mock
import unittest
class RmTestCase(unittest.TestCase):
@mock.patch('mymodule.os.path')
@mock.patch('mymodule.os')
def test_rm(self?? mock_os?? mock_path):
# set up the mock
mock_path.isfile.return_value = False
rm("any path")
# test that the remove call was NOT called.
self.assertFalse(mock_os.remove.called?? "Failed to not remove the file if not present.")
# make the file 'exist'
mock_path.isfile.return_value = True
rm("any path")
mock_os.remove.assert_called_with("any path")
??????????????????????????????????????????κθ??????????o?????????????????????
???????????????????
???????????????????? mock ?????????????????????????????????????????????????????????????????????
?????????????? rm ??????????????????????????????????????????????????????????????????????????????????????????? mock ????????????????????
????#!/usr/bin/env python
????# -*- coding: utf-8 -*-
????import os
????import os.path
????class RemovalService(object):
????"""A service for removing objects from the filesystem."""
????def rm(filename):
????if os.path.isfile(filename):
????os.remove(filename)
????????????????????????????仯??
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import RemovalService
import mock
import unittest
class RemovalServiceTestCase(unittest.TestCase):
@mock.patch('mymodule.os.path')
@mock.patch('mymodule.os')
def test_rm(self?? mock_os?? mock_path):
# instantiate our service
reference = RemovalService()
# set up the mock
mock_path.isfile.return_value = False
reference.rm("any path")
# test that the remove call was NOT called.
self.assertFalse(mock_os.remove.called?? "Failed to not remove the file if not present.")
# make the file 'exist'
mock_path.isfile.return_value = True
reference.rm("any path")
mock_os.remove.assert_called_with("any path")
??????????????? RemovalService ???????????????????????????????????????? RemovalService ??????????????????
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import os.path
class RemovalService(object):
"""A service for removing objects from the filesystem."""
def rm(self?? filename):
if os.path.isfile(filename):
os.remove(filename)
class UploadService(object):
def __init__(self?? removal_service):
self.removal_service = removal_service
def upload_complete(self?? filename):
self.removal_service.rm(filename)
???????????????????? RemovalService ?????????????????????????? UploadService ????????? rm ?????????????????????? UploadService ?? RemovalService.rm ?????????м??????????????????????????????????????????????????????????????????
??????????????????????????
??????? RemovalService.rm ?????????
?????? UploadService ??????????????????????
???????????????????????????з?????????????????????????????????????л???
???????? 1?????????????
????mock ????????????????????????????????????????????????? @mock.patch.object decorator ???????
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from mymodule import RemovalService?? UploadService
import mock
import unittest
class RemovalServiceTestCase(unittest.TestCase):
@mock.patch('mymodule.os.path')
@mock.patch('mymodule.os')
def test_rm(self?? mock_os?? mock_path):
# instantiate our service
reference = RemovalService()
# set up the mock
mock_path.isfile.return_value = False
reference.rm("any path")
# test that the remove call was NOT called.
self.assertFalse(mock_os.remove.called?? "Failed to not remove the file if not present.")
# make the file 'exist'
mock_path.isfile.return_value = True
reference.rm("any path")
mock_os.remove.assert_called_with("any path")
class UploadServiceTestCase(unittest.TestCase):
@mock.patch.object(RemovalService?? 'rm')
def test_upload_complete(self?? mock_rm):
# build our dependencies
removal_service = RemovalService()
reference = UploadService(removal_service)
# call upload_complete?? which should?? in turn?? call `rm`:
reference.upload_complete("my uploaded file")
# check that it called the rm method of any RemovalService
mock_rm.assert_called_with("my uploaded file")
# check that it called the rm method of _our_ removal_service
removal_service.rm.assert_called_with("my uploaded file")
??????????????????? UploadService ?????????????????? rm ???????????????Щ?????????????????????patching mechanism????????滻??????????????е????? RemovalService ????? rm ??????????ζ?????????????????????????????????????????????????????????????????????????????????????