6
  1. Currently I'm writing a unite testing for my flask project. I wrote a function to test the login feature. When I run the unit test, it showed some error message.

FAILED unit_test.py::TestClass::test_login - AttributeError: 'WrapperTestResponse' object has no attribute 'text'

2.Here is my code for the unit testing implementation, I can get the status code successfully but not the text. Did I make some mistakes?

import unittest
from app import app
import requests
from flask import request
import json



class TestClass(unittest.TestCase):
    def setup_class(self):
        app.config['TESTING'] = True  
        self.app = app.test_client()

    def teardown_class(self):
        """Do the testing """
        pass

    def test_login(self):
        response = self.app.get('/login')
        print(response)
        data = {'username': '123456@qq.com', 'password': '12345678'}
        response = app.test_client().post('/login', data=json.dumps(data))
        self.assertEqual(response.status_code, 200)
        print('--------------')
        self.assertEqual(response.text, "Invalid login credentials")
Jay Park
  • 308
  • 1
  • 6
  • 14

1 Answers1

8

I think you are looking for response.data instead

A descriptor that calls get_data() and set_data().

get_data gives

The string representation of the response body...

Example output if your view function returns 'Invalid login credentials':

>>> response.data
b'Invalid login credentials'
5eb
  • 14,798
  • 5
  • 21
  • 65
  • this link goes to Request.data, not the test response class? – jess Feb 03 '22 at 19:01
  • 1
    @jess Thanks for pointing that out. I somehow didn't notice that when I wrote this answer, I've updated it. The links now point to methods of the `werkzeug.wrappers.Response`, because the [werkzeug.test.TestResponse](https://werkzeug.palletsprojects.com/en/2.0.x/test/#werkzeug.test.TestResponse) class is a subclass of `werkzeug.wrappers.Response`. – 5eb Feb 03 '22 at 20:30
  • awesome thanks for the quick answer! – jess Feb 03 '22 at 23:59
  • Did this change in a huge way in recent version of werkzeug? I have a lot of pytest code that uses `requests_mock` and very specifically uses the `text` attribute on all the wrapped response objects. The `data` attribute is bytes, not string, so handling it is actually quite different. – ely Aug 19 '22 at 01:48
  • Digging in the docs, it looks like Flask test clients will return [`test.TestResponse`](https://werkzeug.palletsprojects.com/en/2.2.x/test/#werkzeug.test.TestResponse.text) which does have a `text` attribute that is a proxy for `get_data(as_text=True)`. It's unclear why the return value in the OP's questions for `response` was not a `test.TestResponse` type and instead was a `WrapperTestResponse` - this feels more like a regression in either Flask or Werkzeug than an intentional behavior. – ely Aug 19 '22 at 02:04
  • I can also confirm that for Python 3.8.13, Flask 2.1.3 and Werkzeug 2.2.2, I cannot reproduce the error the OP reported. The `text` attribute works fine. – ely Aug 19 '22 at 02:06
  • @ely Interesting. When I wrote this answer I guess the relevant werkzeug version was 2.0.x, since that's the version my links go to. On [2.2.x](https://werkzeug.palletsprojects.com/en/2.2.x/test/#werkzeug.test.TestResponse.text) I indeed see the `text` property also on 2.1.x. On [2.0.x](https://werkzeug.palletsprojects.com/en/2.0.x/test/#werkzeug.test.TestResponse.text) I don't. – 5eb Aug 19 '22 at 11:04