Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django单元测试与模拟_Python_Django_Unit Testing_Mocking - Fatal编程技术网

Python Django单元测试与模拟

Python Django单元测试与模拟,python,django,unit-testing,mocking,Python,Django,Unit Testing,Mocking,我正在为基于Django类的视图编写一个单元测试 class ExampleView(ListView): def get_context_data(self, **kwargs): context = super(EampleView, self).get_context_data(**kwargs) ## do something else def get_queryset(self, **kwargs): ret

我正在为基于Django类的视图编写一个单元测试

class ExampleView(ListView):

     def get_context_data(self, **kwargs):
         context = super(EampleView, self).get_context_data(**kwargs)
         ## do something else

     def get_queryset(self, **kwargs):
         return self.get_data()

     def get_data(self):
         call_external_API()
         ## do something else
关键问题是
get\u data()
中调用\u external\u API()

当我编写单元测试时,我真的不想调用外部API来获取数据。首先,这将花费我的钱;其次,我可以在另一个测试文件中轻松测试该API

我还可以简单地测试这个
get\u data()
方法,只对它进行单元测试,并模拟
call\u external\u API()
的输出

然而,当我测试整个基于类的视图时,我只会这样做

self.client.get('/example/url/')
并检查状态代码和上下文数据以进行验证


在这种情况下,当我测试整个基于类的视图时,如何模拟此
调用\u external\u API()

在测试基于类的视图时,可以模拟
调用\u external\u API()
方法,如下所示:

import modulea
import unittest
from mock import Mock

class ExampleTestCase(unittest.TestCase):

     def setUp(self):
         self.call_external_api = modulea.call_external_api

     def tearDown(self):
         modulea.call_external_api = self.call_external_api

     def get_data(self):
         modulea.call_external_api = Mock(return_value="foobar")
         modulea.call_external_api()
         ## do something else

你要找的是。您可以通过
MagicMock()
对象修补
调用\u external\u api()

也许您想为类中的所有测试修补
调用\u external\u api()
<代码>补丁基本上提供两种方法

  • 装饰测试类
  • 分别在
    setUp()
    tearDown()中使用
    start()
    stop()
通过
patch
decorator装饰一个类就像装饰所有的测试方法一样(详细信息请参见文档),实现将非常简洁。下面的示例假设您的视图位于
my_view
模块中

@patch("my_view.call_external_api", autospec=True)
class MyTest(unittest.TestCase):
    def setUp(self):
        self.client = Client()

    def test_get_data(self, mock_call_external_api):
        self.client.get('/example/url/')
        self.assertTrue(mock_call_external_api.called)
可以构建更复杂的示例,您可以检查如何调用
mock\u call\u external\u api
,并为api设置返回值或副作用

我没有给出任何关于启动和停止方式的例子(我真的不喜欢),但我想花一些时间讨论两个细节:

  • 我假设在您的
    my\u视图
    模块中定义
    call\u external\u api
    或通过
    从my\u api\u模块导入call\u external\u api
    导入它,否则您应该注意
  • 我使用了
    autospec=True
    :IMHO应该在每个补丁调用中使用它,并很好地解释了原因

  • 不确定你的两个场景有什么不同。你为什么不能用同样的方式来嘲笑它呢?这就是我想要的答案。非常感谢。