在測試過程當中,爲了更好地展開單元測試,mock一些數據跟對象在所不免,下面講一下python的mock的簡單用法。python
關於python mock,網上有不少資料,這裏不會講的特別深,但必定會是實用爲主,看完後,至少可讓你知道mock是怎樣用的。json
1.mock對象方法中的返回數據:api
咱們常常會須要這樣的場景,a系統跟b系統聯調,b系統開發人員進度較慢,有些a須要調用b系統api的返回數據沒辦法拿到,這時候,不改變原來的代碼,但聯調須要保證a系統這邊功能徹底okapp
的場景就能夠用到mock這個模塊了。ide
在這裏,咱們假設b系統完成時是如下這個樣子函數
system_b.pypost
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import requests def send_request(url): r = requests.get(url) return json.loads(r.text) def visit_ustack(): return send_request('http://api.kanzhihu.com/getposts') if __name__ == '__main__': content = visit_ustack() print content
咱們經過調用visit_ustack()這個入口,能夠獲得http://api.kanzhihu.com/getposts這個接口返回的json數據。理想測試狀況下,a系統這邊的測試代碼是這樣的單元測試
system_a.py測試
#!/usr/bin/env python # -*- coding: utf-8 -*- import system_b def system_b_test(): if system_b.visit_ustack()['count'] == 10: print "system b正常,測試經過" else: print "system b異常,測試失敗" system_b_test()
結果顯而易見是這樣的字體
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python /Users/lsf/PycharmProjects/py_pattern/test.py
system b正常,測試經過
Process finished with exit code 0
但如今糟糕的是,系統 b的主體函數send_request還沒開發,咱們沒辦法獲取json格式的數據,固然,現實中能夠經過不少其餘的辦法來解決,但爲了最大程度仿真b系統,如今能夠經過mock來完成這項工做。
現實中功能未完成的a系統
system_a.py
#!/usr/bin/env python # -*- coding: utf-8 -*- def send_request(url): pass def visit_ustack(): return send_request('http://api.kanzhihu.com/getposts') if __name__ == '__main__': content = visit_ustack() print content
system_b.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import mock import system_b def system_b_test(): mock_result = {u'count': 1000, u'publishtime': u'1470798000', u'date': u'2016-08-10', u'id': u'2375'}], u'error': u''} system_b.send_request = mock.Mock(return_value=mock_result) if system_b.visit_ustack()['count'] == 1000: print "system b正常,測試經過" else: print "system b異常,測試失敗" system_b_test()
結果是
/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python /Applications/PyCharm.app/Contents/helpers/pycharm/utrunner.py /Users/lsf/PycharmProjects/py_pattern/test.py true Testing started at 15:24 ... system b正常,測試經過 Process finished with exit code 0 Empty test suite.
在這裏,咱們經過直接mock一個json數據,來達到b系統返回數據的目的,甚至咱們調用的依然是b系統的接口,區別已用紅色字體標出,這個就是mock的操做了。
(1)mock_result:準備須要的mock數據
(2)用mock.Mock(return_value=mock_result)將mock對象設置給系統b對應的返回方法中
值得注意的是,mock.Mock(return_value=mock_result)是一個對象,但爲何system_b.send_request = mock.Mock(return_value=mock_result)返回的是數據而不是對象的其餘屬性跟方法呢,在這裏,是由於mock對象中有一個side_effect屬性,若是這個屬性爲None,就會將return_value設置的值返回。
2.mock對象中的方法:mock.patch跟mock.patch.object
#!/usr/bin/env python # -*- coding: utf-8 -*- import mock class By(object): def add(self, a, b): return a + b + self.multiply(a,b) def multiply(self, a, b): pass b = By() class MockDemo(object): def __init__(self): self.b = b @mock.patch.object(b,'multiply') def test_add(self,mock_multiply): a = 3 b = 5 mock_multiply.return_value = 15 if self.b.add(a,b) == 23: print "mock成功" else: print "mock失敗" if __name__ == '__main__': MockDemo().test_add()
若是mock的是一個函數,則能夠用@mock.patch(target='module.func')來實現。