19

I have exposed my database model using Django-rest-framework view sets and routers, and I am trying to write the unit tests for it.

Here are my API and test code

Viewsets.py

class Model1ViewSet(viewsets.ReadOnlyModelViewSet):

    model = Model1
    serializer_class = Model1Serializer
    filter_class = Model1Filter
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
    ordering = ('id', 'cl1')

Serializer.py

class Model1Serializer(serializers.HyperlinkedModelSerializer):
    chip = serializers.HyperlinkedRelatedField(view_name="some-detail")

    class Meta:
        model = Model1
        fields = ('url', 'id', 'cl1', 'cl2', 'cl3', 'cl4')
        depth = 1

Unit-tests

from rest_framework.test import APIClient

class TestModel1Api(unittest.TestCase):

    def setUp(self):
        self.client = APIClient()

    def test_Model1_list(self):
        response = self.client.get(reverse('Model1-list'))
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_Model1_detail(self):
        mm_objs = Model1.objects.all()
        if mm_objs:
            response = self.client.get(reverse('Model1-detail', args=[mm_objs[0].id]))
            self.assertEqual(response.status_code, status.HTTP_200_OK)

I don't want to connect to the database for unit testing because it falls under integration tests.

Is there any way to mock the database? I know how to apply mocking for standard view functions but here mocking is not working.

  1. How to write the unit tests for my REST-API?
  2. How to mock the database in my unit-tests?
2
  • I'm not familiar with this project so I can't specifically help you there but look in the documentation to find which class/function is actually connecting to the database and mock that out in your tests. Commented Jul 23, 2014 at 9:08
  • 2
    If you want to test the API you can not use unit test at all. Testing the API means calling the view and receiving well formed data from the test database. This would be an integration test as you wrote. The difference between unit and integration tests is not only touching the database or not. Commented Mar 1, 2015 at 15:41

1 Answer 1

9

When you run manage.py test then the base of your database will be created but it contains no data. To do that you can simply create the necessary objects yourself or use something like FactoryBoy

Just keep in mind that the database is cleaned of data from previous test methods when starting a new one.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm curious how one could avoid the use of the database, though. In FactoryBoy you could ideally use something like .prepare() instead of .make() for the recipes to prevent it from persisting the objects in the database but then they wouldn't show up when you go to call the view...
FactoryBoy does support the .build() method which creates the object but it's not saved in the database and won't have an 'id' set. You might be able to make some initial data which will be loaded in during the test database creation and you won't have to populate the tables everytime you run a new test method(you can use the same 'person' object multiple times) but haven't found a better solution
timop: Ah yes, you're right. I was thinking of model mommy in this instance and I got the APIs mixed up. Thanks for the followup.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.