2016-11-06 96 views
2

我開發了一個API(Python 3.5,Django 1.10,DRF 3.4.2),當我從我的UI請求它時,它將視頻文件上傳到我的媒體路徑。那部分工作正常。我嘗試爲此功能編寫測試,但無法使其成功運行。如何用Django REST框架的APIRequestFactory生成文件上傳(測試)請求?

#views.py 

import os 
from rest_framework import views, parsers, response 
from django.conf import settings 


class FileUploadView(views.APIView): 
    parser_classes = (parsers.FileUploadParser,) 
    def put(self, request, filename): 
     file = request.data['file'] 
     handle_uploaded_file(file, filename) 
     return response.Response(status=204) 

def handle_uploaded_file(file, filename): 
    dir_name = settings.MEDIA_ROOT + '/scene/' + filename + '/cam1' 
    new_filename = 'orig.mp4' 
    if not os.path.exists(dir_name): 
     os.makedirs(dir_name) 
    file_path = os.path.join(dir_name, new_filename) 
    with open(file_path, 'wb+') as destination: 
     for chunk in file.chunks(): 
      destination.write(chunk) 

#test.py 

import tempfile 
import os 
from django.test import TestCase 
from django.conf import settings 
from django.core.files import File 
from django.core.files.uploadedfile import SimpleUploadedFile 
from rest_framework.test import APIRequestFactory 
from myapp.views import FileUploadView 


class UploadVideoTestCase(TestCase): 
    def setUp(self): 
     settings.MEDIA_ROOT = tempfile.mkdtemp(suffix=None, prefix=None, dir=None) 

    def test_video_uploaded(self): 
     """Video uploaded""" 
     filename = 'vid' 
     file = File(open('media/testfiles/vid.mp4', 'rb')) 
     uploaded_file = SimpleUploadedFile(filename, file.read(), 'video') 
     factory = APIRequestFactory() 
     request = factory.put('file_upload/'+filename, 
      {'file': uploaded_file}, format='multipart') 
     view = FileUploadView.as_view() 
     response = view(request, filename) 
     print(response) 

     dir_name = settings.MEDIA_ROOT + '/scene/' + filename + '/cam1' 
     new_filename = 'orig.mp4' 
     file_path = os.path.join(dir_name, new_filename) 
     self.assertTrue(os.path.exists(file_path)) 

在這個測試中,我需要使用現有的視頻文件(「媒體/ testfiles/vid.mp4」),並上傳它,因爲我需要測試的一些處理視頻數據後:這就是爲什麼我重置MEDIA_ROOT使用mkdtemp

由於文件沒有上傳,測試失敗。在def put我的views.py,當我打印request我得到<rest_framework.request.Request object at 0x10f25f048>,當我打印request.data我得到沒有什麼。但是,如果我在我的視圖中刪除FileUploadParser並在我的測試中使用request = factory.put('file_upload/' + filename, {'filename': filename}, format="multipart"),則當我打印request.data時,我會得到<QueryDict: {'filename': ['vid']}>

所以我的結論是,我用APIRequestFactory生成的請求是不正確的。 FileUploadParser無法從中檢索原始文件。

因此我的問題:如何使用Django REST Framework的APIRequestFactory生成文件上傳(測試)請求?

有幾個人在SO上提出了接近這個問題的問題,但我沒有提出建議的答案。

任何有關此事的幫助將非常感謝!

回答

4

現在沒事了!從APIRequestFactory切換到APIClient,我設法讓我的測試運行。

我的新test.py:

import os 
import tempfile 
from django.conf import settings 
from django.core.files import File 
from django.core.files.uploadedfile import SimpleUploadedFile 
from django.urls import reverse 
from rest_framework.test import APITestCase, APIClient 
from django.contrib.auth.models import User 

class UploadVideoTestCase(APITestCase): 
    def setUp(self): 
     settings.MEDIA_ROOT = tempfile.mkdtemp() 
     User.objects.create_user('michel') 

    def test_video_uploaded(self): 
     """Video uploaded""" 
     filename = 'vid' 
     file = File(open('media/testfiles/vid.mp4', 'rb')) 
     uploaded_file = SimpleUploadedFile(filename, file.read(), 
      content_type='multipart/form-data') 
     client = APIClient() 
     user = User.objects.get(username='michel') 
     client.force_authenticate(user=user) 
     url = reverse('file_upload:upload_view', kwargs={'filename': filename}) 
     client.put(url, {'file': uploaded_file}, format='multipart') 
     dir_name = settings.MEDIA_ROOT + '/scene/' + filename + '/cam1' 
     new_filename = 'orig.mp4' 
     file_path = os.path.join(dir_name, new_filename) 
     self.assertTrue(os.path.exists(file_path)) 
相關問題