drakenation
drakenation

Reputation: 412

How do I mock a third party library inside a Django Rest Framework endpoint while testing?

The user creation endpoint in my app creates a firebase user (I have a chat room inside the app, powered by firebase) with the same id as my django user.

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 is a wrapper I created around the standard firebase library.

I'm writing my tests like recommended in DRF's guide:

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'])

However, this leads to creating an actual user in Firebase. Not only this fails the test (the firebase library throws an exception), it also hits the actual firebase server, filling it with test data.

How can I either mock or disable the firebase library during my tests?

Upvotes: 4

Views: 2189

Answers (1)

Will Keeling
Will Keeling

Reputation: 22994

It should be straightforward to mock out the firebase_chat import used by your view. One way of doing that is to use the patch decorator from 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()

If you're using Python 2, you will need to pip install mock as it is not bundled with unittest.

Upvotes: 1

Related Questions