Django Rest Framework testing save POST request data

与世无争的帅哥 提交于 2019-12-04 06:44:14

问题


I'm writing some tests for my Django Rest Framework and trying to keep them as simple as possible. Before, I was creating objects using factory boy in order to have saved objects available for GET requests.

Why are my POST requests in the tests not creating an actual object in my test database? Everything works fine using the actual API, but I can't get the POST in the tests to save the object to make it available for GET requests. Is there something I'm missing?

from rest_framework import status
from rest_framework.test import APITestCase

# from .factories import InterestFactory


class APITestMixin(object):
    """
    mixin to perform the default API Test functionality
    """
    api_root = '/v1/'
    model_url = ''
    data = {}

    def get_endpoint(self):
        """
        return the API endpoint
        """
        url = self.api_root + self.model_url
        return url

    def test_create_object(self):
        """
        create a new object
        """
        response = self.client.post(self.get_endpoint(), self.data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data, self.data)
        # this passes the test and the response says the object was created

    def test_get_objects(self):
        """
        get a list of objects
        """
        response = self.client.get(self.get_endpoint())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, self.data)
        # this test fails and says the response is empty [] with no objects


class InterestTests(APITestCase, APITestMixin):
    def setUp(self):
        self.model_url = 'interests/'
        self.data = {
            'id': 1,
            'name': 'hiking',
        }

        # self.interest = InterestFactory.create(name='travel')
        """
        if I create the object with factory boy, the object is 
        there. But I don't want to have to do this - I want to use
        the data that was created in the POST request
        """

You can see the couple lines of commented out code which are the object that I need to create through factory boy because the object does not get created and saved (although the create test does pass and say the object is created).

I didn't post any of the model, serializer or viewsets code because the actual API works, this is a question specific to the test.


回答1:


First of all, Django TestCase (APITestCase's base class) encloses the test code in a database transaction that is rolled back at the end of the test (refer). That's why test_get_objects cannot see objects which created in test_create_object

Then, from (Django Testing Docs)

Having tests altering each others data, or having tests that depend on another test altering data are inherently fragile.

The first reason came into my mind is that you cannot rely on the execution order of tests. For now, the order within a TestCase seems to be alphabetical. test_create_object just happened to be executed before test_get_objects. If you change the method name to test_z_create_object, test_get_objects will go first. So better to make each test independent

Solution for your case, if you anyway don't want database reset after each test, use APISimpleTestCase

More recommended, group tests. E.g., rename test_create_object, test_get_objects to subtest_create_object, subtest_get_objects. Then create another test method to invoke the two tests as needed



来源:https://stackoverflow.com/questions/29287012/django-rest-framework-testing-save-post-request-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!