Django Rest Framework测试保存POST请求数据

时间:2015-03-26 19:15:33

标签: django django-rest-framework django-testing

我正在为我的Django Rest Framework编写一些测试,并试图让它们尽可能简单。之前,我正在使用工厂男孩创建对象,以便保存可用于GET请求的对象。

为什么测试中的POST请求没有在我的测试数据库中创建实际对象?使用实际的API一切正常,但我无法在测试中获得POST以保存对象以使其可用于GET请求。有什么我想念的吗?

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
        """

你可以看到几行注释掉的代码是我需要通过工厂男孩创建的对象,因为对象没有被创建和保存(虽然创建测试确实传递并说出对象已创建。)

我没有发布任何模型,序列化程序或视图集代码,因为实际的API有效,这是测试特有的问题。

1 个答案:

答案 0 :(得分:4)

首先,Django TestCaseAPITestCase的基类)将测试代码包含在数据库事务中,该事务在测试结束时回滚(refer)。这就是为什么test_get_objects无法看到test_create_object

中创建的对象的原因

然后,从(Django Testing Docs

  

让测试改变彼此的数据,或者让测试依赖于另一个测试改变数据本身就是脆弱的。

我想到的第一个原因是你不能依赖测试的执行顺序。目前,TestCase中的顺序似乎是按字母顺序排列的。 test_create_object恰好在test_get_objects之前被执行了。如果您将方法名称更改为test_z_create_objecttest_get_objects将首先出现。最好让每个测试独立

针对您的案例的解决方案,如果您仍然希望在每次测试后重置数据库,请使用APISimpleTestCase

更多推荐,小组测试。例如,将test_create_objecttest_get_objects重命名为subtest_create_objectsubtest_get_objects。然后创建另一个测试方法以根据需要调用两个测试