在做一些項(xiàng)目的時(shí)候,因?yàn)橛玫搅说谌降慕涌?,而第三方的接口可能沒有做好或者第三方的接口不方便訪問的時(shí)候,一般都會用到Mock的技術(shù)。
Mock這個(gè)詞在英語中有模擬的這個(gè)意思。Python3.x中本身就自帶了Mock庫,(Python2.x中還是單獨(dú)的)Mock是Python中一個(gè)用于支持單元測試的庫,它的主要功能是使用mock對象替代掉指定的Python對象,以達(dá)到模擬對象的行為。
簡單的說,mock庫用于如下的場景:
假設(shè)你開發(fā)的項(xiàng)目叫a,里面包含了一個(gè)模塊b,模塊b中的一個(gè)函數(shù)c(也就是a.b.c)在工作的時(shí)候需要調(diào)用發(fā)送請求給特定的服務(wù)器來得到一個(gè)JSON返回值,然后根據(jù)這個(gè)返回值來做處理。如果要為a.b.c函數(shù)寫一個(gè)單元測試,該如何做?
一個(gè)簡單的辦法是搭建一個(gè)測試的服務(wù)器,在單元測試的時(shí)候,讓a.b.c函數(shù)和這個(gè)測試服務(wù)器交互。但是這種做法有兩個(gè)問題:
1 . 測試服務(wù)器可能很不好搭建,或者搭建效率很低。
2 . 你搭建的測試服務(wù)器可能無法返回所有可能的值,或者需要大量的工作才能達(dá)到這個(gè)目的。
httmock庫是基于Mock庫的,它更方便于用requests的方式來返回接口的值。

使用pip命令來安裝:
pip install httmock
用法:
1 您可以使用它來模擬第三方API和在內(nèi)部使用 requests 的測試庫,有條件地使用urlmatch裝飾器:
from httmock import urlmatch, HTTMock
import requests
@urlmatch(netloc=r'(.*\.)?google\.com$')
def google_mock(url, request):
return ('Feeling lucky, punk?')
with HTTMock(google_mock):
r = requests.get('http://google.com/')
print(r.content)
控制臺顯示:
b'Feeling lucky, punk?'
2 all_requests裝飾器沒有條件地阻止實(shí)際的請求。 如果您返回一個(gè)字典,它將映射到返回的“request.Response”對象:
from httmock import all_requests, HTTMock
import requests
@all_requests
def response_content(url, request):
return {'status_code': 200,
'content': 'Oh hai'}
with HTTMock(response_content):
r = requests.get('https://foo_bar')
print (r.status_code)
print (r.content)
控制臺顯示:
200
b'Oh hai'
3 如果你傳遞Set-Cookie頭,request.Response.cookies將包含這些值。 您也可以直接使用response方法,而不是返回一個(gè)dict:
from httmock import all_requests, response, HTTMock
import requests
@all_requests
def response_content(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
content = {'message': 'API rate limit exceeded'}
return response(403, content, headers, None, 5, request)
with HTTMock(response_content):
r = requests.get('https://api.github.com/users/whatever')
print (r.json().get('message'))
print (r.cookies['foo'])
控制臺顯示:
API rate limit exceeded
bar
CC先生說:
要明白上面的例子,預(yù)備知識至少需要有:
-Python 中requests庫的用法
-Python中裝飾器的用法
or 你直接套用上面的用法就可以返回第三方接口或者依賴的模塊的值了。
以上
