【问题标题】:Django: Avoid HTTP API calls while testing from django viewsDjango:从 Django 视图进行测试时避免 HTTP API 调用
【发布时间】:2015-09-07 07:49:04
【问题描述】:

我正在为 django 视图编写测试,其中一些视图正在发出外部 HTTP 请求。在运行测试时,我不想执行这些 HTTP 请求。由于在测试期间,正在使用的数据是虚拟的,因此这些 HTTP 请求不会按预期运行。

对此有哪些可能的选择?

【问题讨论】:

    标签: django django-testing


    【解决方案1】:

    您可以覆盖测试中的设置,然后在视图中检查该设置。 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
    

    因为到处都有这些会相当混乱,我建议创建一个看起来像这样的 mixin。

    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')
    

    【讨论】:

    • 似乎不是通过应用程序代码插入这种情况的优雅解决方案,
    • 您是对的,如果您在任何地方都手动执行此操作。但这就是继承的用武之地。我可能会创建一个自定义基本视图,或者只是一个非常简单的 mixin 和一个基本函数,它只使用给定的 URL 进行 api 调用,检查这些设置,然后在整个应用程序中使用该函数。如果你愿意,我可以向你展示那会是什么样子。
    【解决方案2】:

    这就是模拟的用武之地。在您的测试中,您可以使用库来修补您正在测试的代码部分,以返回您期望的测试结果,绕过该代码实际执行的操作。

    您可以阅读一篇关于 Python 模拟 here 的精彩博文。

    如果您使用的是 Python 3.3 或更高版本,则 mock 库包含在 Python 中。如果没有,你可以从PyPI下载。

    如何模拟您正在进行的调用的具体细节将取决于您的视图代码究竟是什么样的。

    【讨论】:

    • 你分享的好文章,这可以用来模拟代码的某些部分。但不知道如何整体测试 django 视图。
    【解决方案3】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-15
      • 2020-10-09
      • 2020-11-02
      • 2012-07-24
      • 2019-03-09
      • 1970-01-01
      • 2021-08-26
      • 2010-11-24
      相关资源
      最近更新 更多