Django Rest Framework测试保存POST请求数据 [英] Django Rest Framework testing save POST request data

查看:293
本文介绍了Django Rest Framework测试保存POST请求数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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).

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

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.

推荐答案

首先,Django TestCase APITestCase 的基类)将测试代码包含在数据库事务中,该数据库事务在测试结束时回滚(参阅)。这就是 test_get_objects 无法看到在 test_create_object中创建的对象

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

然后,来自( Django测试文档


正在测试相互更改数据,或依赖其他测试进行数据更改本质上是脆弱的。

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 。因此,最好使每个测试独立进行

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

解决方案,如果您还是不想在每次测试后重置数据库,请使用 APISimpleTestCase

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

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

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

这篇关于Django Rest Framework测试保存POST请求数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆