有没有一种方法可以覆盖Django中的模型方法?

时间:2019-03-20 18:36:12

标签: django django-models django-testing

我有一个这样的模型:

class Car(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    create_date = models.DateTimeField('date added', auto_now_add=True)
    modify_date = models.DateTimeField('date modified', auto_now=True)
    ...

    def last_tracked_location(self):
        ...
        try:
            url = 'myurl'
            return requests.get(
                url,
            ).json()['location'])
        except:
            return False

稍后将在管理员面板中调用此方法。它从api请求某些内容,然后返回this或false。

在测试模式下,其他api不存在,因此请求将所有测试延迟到超时,然后返回False

是否有一种方法可以覆盖它?我检查了docs,但只能找出要覆盖的设置。

我的另一个想法是,如果在测试模式下调用该方法,则要在方法内部进行测试,然后再从不进入该try块。但是我不认为这是一种干净的方法。

更新

我这样调用测试:

python3 manage.py test --settings=app.settings_test

2 个答案:

答案 0 :(得分:2)

在我看来,直接在方法中检查DEBUG并不是很干净。 也许最好编写一些API类来发出此请求?

然后,您可以为该类编写单独的逻辑以在“测试模式”下运行(不确定我是否正确理解您的意思:) test env?)或仅在测试中创建模拟。

在这里您可以阅读有关条件测试场景的更多信息: https://realpython.com/testing-third-party-apis-with-mocks/

答案 1 :(得分:1)

您可以编写测试,以便它们模拟API的响应。 unittest mock模块是一个很好的起点,并且是自Python 3.3以来的Python标准库的一部分。

我无权访问您的完整代码,但这是一个让您入门的示例:

from unittest import mock
from django.test import TestCase
from .models import Car


@mock.patch('yourapp.models.Car.last_tracked_location')
class CarTestCase(TestCase):
    def test_get_last_tracked_location(self, mock_last_tracked_location):
        mock_last_tracked_location.return_value = {'location': 'Paris'}
        car = Car.objects.create()
        response = car.last_tracked_location()
        assert response['location'] == 'Paris'