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

Django Rest Framework testing save POST request data

我正在为我的 Django Rest Framework 编写一些测试,并试图让它们尽可能简单。之前,我使用 factory boy 创建对象,以便保存可用于 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
        """

您可以看到几行注释掉的代码,它们是我需要通过 factory boy 创建的对象,因为该对象没有被创建和保存(尽管创建测试 确实传递并说对象已创建)。

我没有 post 任何模型、序列化器或视图集代码,因为实际 API 有效,这是一个特定于测试的问题。

首先,Django TestCaseAPITestCase的基础class)将测试代码封装在一个数据库事务中,在测试结束时回滚(refer).这就是为什么 test_get_objects 看不到在 test_create_object

中创建的对象的原因

然后,从 (Django Testing Docs)

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

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

针对您的情况的解决方案,如果您不想在每次测试后重置数据库,请使用 APISimpleTestCase

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