如何在测试时模拟Django Rest Framework端点内的第三方库?

时间:2018-03-27 23:31:47

标签: django testing django-rest-framework

我的应用中的用户创建端点创建了一个firebase用户(我在应用内部有一个聊天室,由firebase提供支持),其ID与我的django用户相同。

from django.contrib.auth.models import User
from rest_framework import generics
from rest_framework import permissions
from apps.core.services import firebase_chat

class UserCreate(generics.GenericAPIView):

    permission_classes = [permissions.AllowAny]

    @transaction.atomic
    def put(self, request):
        user = User.objects.create(**request.data)
        firebase_chat.create_user(user)

firebase_chat是我在标准firebase库周围创建的包装器。

我正在编写我在DRF指南中推荐的测试:

from django.urls import reverse
from django.test import TestCase
from rest_framework.test import APIClient

class UserCreateTest(TestCase):

    def test_user_create__all_valid__user_created(self):
        client = APIClient()
        client.force_authenticate(user=User.objects.create(username='test'))
        response = client.put(reverse('user-create'))
        self.assertTrue(response.data['something'])

但是,这会导致在Firebase中创建实际用户。这不仅会导致测试失败(firebase库引发异常),它还会命中实际的firebase服务器,并为其填充测试数据。

如何在测试期间模拟或禁用firebase库?

1 个答案:

答案 0 :(得分:1)

模拟视图使用的firebase_chat导入应该很简单。一种方法是使用patch中的unittest.mock装饰器。

from django.urls import reverse
from django.test import TestCase
from rest_framework.test import APIClient
from unittest.mock import patch


class UserCreateTest(TestCase):

    @patch('your.app.view.firebase_chat')
    def test_user_create__all_valid__user_created(self, mock_firebase_chat):
        client = APIClient()
        client.force_authenticate(user=User.objects.create(username='test'))
        response = client.put(reverse('user-create'))
        self.assertTrue(response.data['something'])
        # Assert that `create_user` was called
        mock_firebase_chat.create_user.assert_called()

如果您使用的是Python 2,则需要pip install mock,因为它不与unittest捆绑在一起。