4

I have something like this:

def upload_something(request):
    data = {}
    if request.FILES:
        raw_file = request.FILES['myfile'].read()
    else:
        raw_file = request.raw_post_data

I can't seem to be able to write a unit-test that populates raw_post_data, how would I go about doing that? I basically just want to send an image file. I'm trying to create a test case for when I read raw_post_data and it errors with:

You cannot access raw_post_data after reading from request's data stream

Kit Sunde
  • 32,665
  • 22
  • 111
  • 176

4 Answers4

2

I'm assuming you have figured this out by now, but as the answers are almost out of date with the deprecation of raw_post_data I thought i'd post.

def test_xml_payload(self):
    data = '<?xml version="1.0" encoding="UTF-8"?><blah></blah>'
    response = self.client.post(reverse('my_url'),
                                data=data,
                                content_type='application/xml')


def my_view(request):
    xml = request.body
Danger
  • 133
  • 2
  • 10
1

You can use mocking. Some examples available here and in docs here


Updated

Kit, I think it's very depends on your test case. But in general you shouldn't use raw_post_data directly. Instead it's have to be patched like in example below:

from mock import Mock, MagicMock

class SomeTestCase(TestCase):

    def testRawPostData(self):
        ...

        request = Mock(spec=request)
        request.raw_post_data = 'myrawdata'
        print request.raw_post_data  # prints 'myrawdata'

        file_mock = MagicMock(spec=file)
        file_mock.read.return_value = 'myfiledata'
        request.FILES = {'myfile': file_mock}    
        print request.FILES['myfile'].read()  # prints 'myfiledata'
Community
  • 1
  • 1
Alexey Savanovich
  • 1,815
  • 10
  • 19
  • The test case I'm trying to cover is that when I read `raw_post_data` it's telling me that I've already read the data before, which I don't think would be possible to hit via Mock. – Kit Sunde Dec 22 '11 at 02:51
  • Kit, I'm just updated the answer. If you still sure that the mocking doesn't cover your needs, please provide your tests code. – Alexey Savanovich Dec 27 '11 at 14:08
1

The error message the interpreter is giving is correct. After you access the POST data via if request.FILES, you can no longer access the raw_post_data. If in your actual code (not the tests) you hit that line, it would error with the same message. Basically, you need two separate views for form-based POSTS and direct file POSTS.

jeffknupp
  • 5,166
  • 2
  • 24
  • 29
0

I took this listing here

c = Client()
f = open('wishlist.doc')
c.post('/customers/wishes/', {'name': 'fred', 'attachment': f})
f.close()

Client is a special class for testing your views. This is the example of posting files to your view. It's part of Django testing framework.

Ilya
  • 1,212
  • 11
  • 16