1. 程式人生 > >python mock接口返回數據(轉載)

python mock接口返回數據(轉載)

pty obj bin 對象 cati 調用 tro demo 直接

在測試過程中,為了更好地展開單元測試,mock一些數據跟對象在所難免,下面講一下python的mock的簡單用法。

關於python mock,網上有很多資料,這裏不會講的特別深,但一定會是實用為主,看完後,至少可以讓你知道mock是怎樣用的。

1.mock對象方法中的返回數據:

我們經常會需要這樣的場景,a系統跟b系統聯調,b系統開發人員進度較慢,有些a需要調用b系統api的返回數據沒辦法拿到,這時候,不改變原來的代碼,但聯調需要保證a系統這邊功能完全ok

的場景就可以用到mock這個模塊了。

在這裏,我們假設b系統完成時是以下這個樣子

system_b.py

技術分享圖片
#!/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‘)來實現。

python mock接口返回數據(轉載)