4

I have a strange problem in a Django template test. When the test executes my view, the view returns an HttpResponse object. However, when I then pass that response object to the Django TestCase assertContains method, the response object becomes a string. Since this string doesn't have a 'status_code' attribute like a response object does, the test fails. Here's my code:

template_tests.py

from django.test import TestCase
from django.test.client import RequestFactory

class TestUploadMainPhotoTemplate(TestCase):
    def setUp(self):
        self.factory = RequestFactory()

    def test_user_selects_non_jpeg_photo_file(self):
        """
        User is trying to upload a photo file via a form
        with an ImageField.  However, the file doesn't have
        a '.jpg' extension so the form's is_valid function, which
        I've overridden, flags this as an error and returns False.
        """
        with open('photo.png') as test_photo:
            request = self.factory.post(reverse('upload-photo'), 
                                        {'upload_photo': '[Upload Photo]',
                                         'photo': test_photo})
        kwargs = {'template': 'upload_photo.html'}
        response = upload_photo(request, **kwargs)
        # pdb.set_trace()
        self.assertContains(response, 'Error: photo file must be a JPEG file')

When I run this code in the debugger and do 'type(response)' before I call assertContains, I can see that 'response' is a HttpResponse object. However, when assertContains is called, I get this error:

AttributeError: 'str' object has no attribute 'status_code'

I set an additional breakpoint in the assertContains method at the location .../django/test/testcases.py:638:

self.assertEqual(response.status_code, status_code...

At this point, when I do 'type(response)' again, I see that it has become a string object and doesn't have a status_code attribute. Can anyone explain what's going on? I've used this same test pattern successfully in a dozen other template tests and it worked in all of them. Could it have something to do with the fact that this test involves uploading a file?

Thanks.

dan-klasson
  • 13,734
  • 14
  • 63
  • 101
Jim
  • 13,430
  • 26
  • 104
  • 155

2 Answers2

1

I had a similar problem and solved it by looking at assertContains, it doesn't really help you but who knows ?

void assertContains( SimpleTestCase self, WSGIRequest response, text, count = ..., int status_code = ..., string msg_prefix = ..., bool html = ... )

Asserts that a response indicates that some content was retrieved successfully, (i.e., the HTTP status code was as expected), and that text occurs count times in the content of the response. If count is None, the count doesn't matter - the assertion is true if the text occurs at least once in the response.

Could it have something to do with the fact that this test involves uploading a file?

Sure, as I successfully wrote my test for a simple HttpResponse :

response = self.client.get('/administration/', follow=True)
self.assertContains(response, '<link href="/static/css/bootstrap.min.css" rel="stylesheet">',msg_prefix="The page should use Bootstrap")

So I am not really helping, but maybe this could help somebody a little.

Mickaël
  • 3,763
  • 5
  • 26
  • 32
0

I had a similar problem handling Json Response .

self.assertEquals(json.loads(response.content),{'abc': True})

Following fixed the problem for me.

Ayub Khan
  • 896
  • 2
  • 14
  • 17