Django:从 Django 视图进行测试时避免 HTTP API 调用
Django: Avoid HTTP API calls while testing from django views
我正在为 Django 视图编写测试,一些视图正在发出外部 HTTP 请求。虽然 运行 我不想执行这些 HTTP 请求的测试。由于在测试期间,正在使用的数据是虚拟的,因此这些 HTTP 请求不会按预期运行。
对此有哪些可能的选择?
您可以覆盖测试中的设置,然后在您的视图中检查该设置。 Here 是覆盖设置的文档。
from django.conf import settings
if not settings.TEST_API:
# api call here
然后你的测试看起来像这样
from django.test import TestCase, override_settings
class LoginTestCase(TestCase):
@override_settings(TEST_API=True)
def test_api_func(self):
# Do test here
因为到处都是这些东西会相当混乱,我建议创建一个看起来像这样的混合。
class SensitiveAPIMixin(object):
def api_request(self, url, *args, **kwargs):
from django.conf import settings
if not settings.TEST_API:
request = api_call(url)
# Do api request in here
return request
然后,通过多重继承的力量,您需要向此 api 调用发出请求的视图可以执行类似的操作。
class View(generic.ListView, SensitiveAPIMixin):
def get(self, request, *args, **kwargs):
data = self.api_request('http://example.com/api1')
这就是 mocking 的用武之地。在您的测试中,您可以使用库将正在测试的代码部分修补为 return 您期望的测试结果,绕过该代码实际执行的操作.
您可以在 Python here.
中阅读一篇关于模拟的好博客 post
如果您使用的是 Python 3.3 或更高版本,mock library is included in Python. If not, you can download it from PyPI.
如何模拟您正在进行的调用的具体细节将取决于您的视图代码究竟是什么样子。
Ben 说得对,但这里有一些伪代码可能会有所帮助。此处的补丁假设您正在使用 requests
,但根据需要更改路径以模拟出您需要的内容。
from unittest import mock
from django.test import TestCase
from django.core.urlresolvers import reverse
class MyTestCase(TestCase):
@mock.patch('requests.post') # this is all you need to stop the API call
def test_my_view_that_posts_to_an_api(self, mock_get):
response = self.client.get(reverse('my-view-name'))
self.assertEqual('my-value', response.data['my-key'])
# other assertions as necessary
我正在为 Django 视图编写测试,一些视图正在发出外部 HTTP 请求。虽然 运行 我不想执行这些 HTTP 请求的测试。由于在测试期间,正在使用的数据是虚拟的,因此这些 HTTP 请求不会按预期运行。
对此有哪些可能的选择?
您可以覆盖测试中的设置,然后在您的视图中检查该设置。 Here 是覆盖设置的文档。
from django.conf import settings
if not settings.TEST_API:
# api call here
然后你的测试看起来像这样
from django.test import TestCase, override_settings
class LoginTestCase(TestCase):
@override_settings(TEST_API=True)
def test_api_func(self):
# Do test here
因为到处都是这些东西会相当混乱,我建议创建一个看起来像这样的混合。
class SensitiveAPIMixin(object):
def api_request(self, url, *args, **kwargs):
from django.conf import settings
if not settings.TEST_API:
request = api_call(url)
# Do api request in here
return request
然后,通过多重继承的力量,您需要向此 api 调用发出请求的视图可以执行类似的操作。
class View(generic.ListView, SensitiveAPIMixin):
def get(self, request, *args, **kwargs):
data = self.api_request('http://example.com/api1')
这就是 mocking 的用武之地。在您的测试中,您可以使用库将正在测试的代码部分修补为 return 您期望的测试结果,绕过该代码实际执行的操作.
您可以在 Python here.
中阅读一篇关于模拟的好博客 post如果您使用的是 Python 3.3 或更高版本,mock library is included in Python. If not, you can download it from PyPI.
如何模拟您正在进行的调用的具体细节将取决于您的视图代码究竟是什么样子。
Ben 说得对,但这里有一些伪代码可能会有所帮助。此处的补丁假设您正在使用 requests
,但根据需要更改路径以模拟出您需要的内容。
from unittest import mock
from django.test import TestCase
from django.core.urlresolvers import reverse
class MyTestCase(TestCase):
@mock.patch('requests.post') # this is all you need to stop the API call
def test_my_view_that_posts_to_an_api(self, mock_get):
response = self.client.get(reverse('my-view-name'))
self.assertEqual('my-value', response.data['my-key'])
# other assertions as necessary