python - 我如何在我的 Django 应用程序中模拟一个到达外部服务的组件?

标签 python django testing mocking

我有一个方法可以连接到外部 API 并提取一些内容,然后执行一些逻辑并继续进行。问题是,在测试时,我不希望我的测试用例触发这个外部 API,但我确实希望它模拟响应。示例

def create_animals(candidate):
    if ExternalService.get_candidate_validity(candidate):
         print('Things are good, go ahead')
         #creates the animal objects etc....

但是 ExternalService.get_candidate_validity 访问了我想要模拟的 API。我知道我可以模拟这样的实例:

get_candidate_validity_value = {'response': True}
c = ExternalService('someparamsthatineed')
c.get_candidate_validity = MagicMock(return_value=get_candidate_validity_value)

但是我如何处理在我最终调用测试的方法中实例化类的情况?

最佳答案

如果你有一个 python 模块 animals.py 有这个:

def create_animals(candidate):
    if ExternalService.get_candidate_validity(candidate):
         print('Things are good, go ahead')
         #creates the animal objects etc....

您可以在 test_animals.py 中以这种方式模拟它

from mock import MagicMock  # or import mock from stdlib unittest in python 3

def test_create_animals():
    from path.to.animals import ExternalService, create_animals
    ExternalService.get_candidate_validity = MagicMock(return_value=True)
    animals = create_animals('foo')
    ExternalService.get_candidate_validity.assert_called_with('foo')

单元测试的最佳实践是以某种方式模拟所有外部服务,这样您就可以测试单元,即被测试的功能,而不是其他任何东西。

另一种方法是使用标准单元测试库中的补丁功能。

https://docs.python.org/3/library/unittest.mock.html#attaching-mocks-as-attributes

>>> with patch('animals.ExternalService') as MockClass:
...     MockClass.get_candidate_validity.return_value = 'foo'

关于python - 我如何在我的 Django 应用程序中模拟一个到达外部服务的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50164756/

相关文章:

python - 比较 2 个字符串而不考虑 Python 中的重音

python - 比较 Pandas 中两个数据框的行

Django Sites 模块里面的SITE_ID为什么等于1

Python,RegEx,替换匹配的某个部分

python - 我如何测量我的算法在整个运行过程中所花费的时间?

python - 对 Tastypie 的 POST 请求返回一个非 SSL Location Header

django - 如何要求 Django 多关系管理器同时匹配多个关系?

php - mock php测试中的碳对象

android - './gradlew -Dtest.single=SimpleTest test' 运行我拥有的所有测试

php - Selenium、php、phpUnit、404 错误调用 testComplete() 而不是继续,我该如何停止?