Python单元测试模拟API密钥
我正在为Client.py的Python单元测试模拟API密钥,python,mocking,api-key,python-unittest,Python,Mocking,Api Key,Python Unittest,我正在为Client.py的Client类编写单元测试,该类查询API。每个测试都用c=client.client(“apikey”)实例化客户机。一次运行一个测试可以正常工作,但运行所有测试(例如使用py.test)时,我会得到一个401:“异常:响应401:未经授权的访问。请求必须包含有效的api密钥。” 我有一个有效的API密钥,但这不应该包括在单元测试中。如果您能解释一下为什么“apikey”只适用于一个查询,我将不胜感激。更具体地说,如何模拟对API的调用?下面是一个单元测试示例: d
Client
类编写单元测试,该类查询API。每个测试都用c=client.client(“apikey”)
实例化客户机。一次运行一个测试可以正常工作,但运行所有测试(例如使用py.test
)时,我会得到一个401:“异常:响应401:未经授权的访问。请求必须包含有效的api密钥。”
我有一个有效的API密钥,但这不应该包括在单元测试中。如果您能解释一下为什么“apikey”
只适用于一个查询,我将不胜感激。更具体地说,如何模拟对API的调用?下面是一个单元测试示例:
def testGetContextReturnFields(self):
c = client.Client("apikey")
contexts = c.getContext("foo")
assert(isinstance(contexts[0]["context_label"], str))
assert(contexts[0]["context_id"] == 0)
将API调用和
Client.getContext()方法的测试分开。要显式测试API调用,请修补请求对象
import client
import httpretty
import requests
from mock import Mock, patch
...
def testGetQueryToAPI(self):
"""
Tests the client can send a 'GET' query to the API, asserting we receive
an HTTP status code reflecting successful operation.
"""
# Arrange: patch the request in client.Client._queryAPI().
with patch.object(requests, 'get') as mock_get:
mock_get.return_value = mock_response = Mock()
mock_response.status_code = 200
# Act:
c = client.Client()
response = c._queryAPI("path", 'GET', {}, None, {})
# Assert:
self.assertEqual(response.status_code, 200)
# Repeat the same test for 'POST' queries.
对于测试getContext()
,使用httprety模拟HTTP
@httpretty.activate
def testGetContextReturnFields(self):
"""
Tests client.getContext() for a sample term.
Asserts the returned object contains the corrcet fields and have contents as
expected.
"""
# Arrange: mock JSON response from API, mock out the API endpoint we expect
# to be called.
mockResponseString = getMockApiData("context_foo.json")
httpretty.register_uri(httpretty.GET,
"http://this.is.the.url/query",
body=mockResponseString,
content_type="application/json")
# Act: create the client object we'll be testing.
c = client.Client()
contexts = c.getContext("foo")
# Assert: check the result object.
self.assertTrue(isinstance(contexts, list),
"Returned object is not of type list as expected.")
self.assertTrue(("context_label" and "context_id") in contexts[0],
"Data structure returned by getContext() does not contain"
" the required fields.")
self.assertTrue(isinstance(contexts[0]["context_label"], str),
"The \'context_label\' field is not of type string.")
self.assertEqual(contexts[0]["context_id"], 0,
"The top context does not have ID of zero.")
模拟的内容和方式在很大程度上取决于客户机
类的内部结构。毕竟,您可以只模拟Client.getContext
来返回一些已修复的内容,但是您只是在测试您是否将模拟配置为与预期的输出相匹配。我不确定我是否理解正确:您想通过实际调用API来测试Client
?您应该信任API(您不能再次测试API),只需测试您的客户端是否进行了正确的调用。@Micheled'Amico我如何测试我的客户端在不实际查询API的情况下对API进行了正确的查询?如果不知道API是什么,很难回答。在某些情况下,您可以编写自己的直接接口(API调用的1-1),如果它是http API,您可以用一个假的测试环境或模拟http请求来替换它。在Python中,简单地直接模拟库而不创建自己的接口:这种方式是C、C++和java的最佳实践。看看