如何在django mock中容纳一个查询字符串

时间:2017-11-01 14:35:37

标签: python django unit-testing

我完全被这个难以理解,因为我甚至不知道该怎么去谷歌。我不熟悉python测试(我主要在javascript中工作)。

我在python / django中有一个端点,我添加了一个查询字符串。这是端点(我已经更改了一些名称以使其更通用):

class ThingSeriesView(APIView):
"""
Ajax Request for just the Thing Series data
"""
renderer_classes = (JSONRenderer, )

def get(self, request, pk, **kwargs):  # pylint: disable=invalid-name
    """
    :param request:
    :param pk:
    :return:
    """
    thing = get_object_or_404(models.Thing, pk=pk)
    frequency = float(request.GET.get('frequency', '1.0'))

    serializer = ChartDataSeriesSerializer(
        thing.get_series(frequency))

    return Response(serializer.data)

我添加的行是(这导致问题):

frequency = float(request.GET.get('frequency', '1.0'))

thing.get_series最初只是为了一切而传递了“1.0”。

这很好,它可以满足我的需要,但它打破了测试:

class TestThingSeriesView(object):
"""
Test the ThingSeries view
"""

def test_get(self):
    thing = models.Thing()
    # pylint: disable=line-too-long
    with patch('main.endpoints.get_object_or_404', new_callable=Mock) as mock_get_obj,\
         patch('main.endpoints.Response', new_callable=Mock) as mock_response,\
         patch.object(thing, 'get_series') as series_method:

        endpoint = endpoints.ThingSeriesView()
        mock_get_obj.return_value = thing

        assert endpoint.get(Mock, 'foo') == mock_response.return_value

        mock_get_obj.assert_called_once()
        series_method.assert_called_with(1.0)

这是我得到的错误:

>       frequency = float(request.GET.get('frequency', '1.0'))
E       AttributeError: type object 'Mock' has no attribute 'GET'

如何重写测试以便传入自定义频率值?我猜我需要导入请求,但之后我不知道该怎么办。

或者,我在端点做错了吗? (我不这么认为,因为它正在做我想做的事。)

1 个答案:

答案 0 :(得分:0)

没有必要做那些模拟,记住模拟是邪恶的,它可以隐藏代码中的错误,上面的测试可以完全没有任何嘲弄。

您应该重构测试以使用RequestFactoryTransactionTestCase。顺便说一下,我看到你正在使用rest框架,所以你可以使用APIRequestFactory从django扩展RequestFactory。这样的事情应该有效:

from django.test import TransactionTestCase
from rest_framework.test import APIRequestFactory
from your_models import Thing

class TestThingSeriesView(TransactionTestCase):
    """
    Test the ThingSeries view
    """
    def setUp(self):
        self.factory = APIRequestFactory()

    def test_get(self):
        thing = Thing.objects.create() # create your model here
        request = self.factory.get('thing_url') 
        response = ThingSeriesView.as_view()(request, thing.id)

        # your assertions on the response