在Django中,如何在导入过程中模拟由views.py调用的对象方法?

时间:2019-04-09 22:17:01

标签: python django python-unittest python-mock

我正在为我的Django应用程序编写系统测试,在其中我通过HTTP请求测试完整的应用程序并模拟其外部依赖项的API。

views.py 中,我有类似的内容:

from external_service import ExternalService
externalService = ExternalService
data = externalService.get_data()

@crsf_exempt
def endpoint(request):
    do_something()

我想要的是模拟(或存根)ExternalService以在调用其方法get_data()时返回预定义的响应。

问题是,当我运行python manage.py test时,views.py会在测试类之前加载。因此,当我用模拟对象修补对象时,已经调用了函数get_data()。

This solution也不起作用。

1 个答案:

答案 0 :(得分:0)

首先,不要在导入时调用您的方法。当然没必要吗?

如果get_data做类似get的请求,例如

def get_data():
    response = requests.get(DATA_URL)
    if response.ok:
        return response
    else:
        return None

然后您就可以模拟它;

from unittest.mock import Mock, patch

from nose.tools import assert_is_none, assert_list_equal

from external_service import ExternalService


@patch('external_service.requests.get')
def test_getting_data(mock_get):
    data = [{
        'content': 'Response data'
    }]

    mock_get.return_value = Mock(ok=True)
    mock_get.return_value.json.return_value = data

    response = ExternalService.get_data()

    assert_list_equal(response.json(), data)


@patch('external_service.requests.get')
def test_getting_data_error(mock_get):
    mock_get.return_value.ok = False

    response = ExternalService.get_data()

    assert_is_none(response)

为此,如果您还没有pip install nose,则需要它。