我正在为基于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
关键问题是call_external_API()
中的get_data()
。
当我编写单元测试时,我真的不想调用外部API来获取数据。首先,这将耗费我的钱;第二,我可以在另一个测试文件中轻松测试该API。
我也可以通过仅对其进行单元测试并模拟get_data()
的输出来轻松测试此call_external_API()
方法。
然而,当我测试这个基于类的整个视图时,我只会做
self.client.get('/example/url/')
并检查状态代码和上下文数据以进行验证。
在这种情况下,当我测试整个基于类的视图时,如何模拟此call_external_API()
?
答案 0 :(得分:1)
您正在寻找的是patch
from unittest.mock
。您可以通过call_external_api()
对象修补MagicMock()
。
也许您想在课堂上为所有测试修补call_external_api()
。 patch
向你提供两种方式来实现它
start()
和stop()
中使用setUp()
和tearDown()
装饰一个类patch
装饰器就像装饰所有测试方法(详见文档),实现非常简洁。以下示例假设您的视图位于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_call_external_api
并为API设置返回值或副作用。
我没有提供任何关于开始和停止方式的例子(我不太喜欢)但我想花一些时间在两个细节上:
my_view
模块中定义call_external_api
或者按from my_API_module import call_external_api
导入它,否则您应该注意Where to patch autospec=True
:恕我直言,它应该在每个补丁调用中使用,documentation解释为什么非常好答案 1 :(得分:0)
在使用类似的方法测试基于分类的视图时,您可以模拟call_external_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