I have a simple test case which checks that POST
request with valid data returns an HTML response with 200 status code:
class PostRequestTestCase(TestCase):
def test_valid_post_request(self):
response = self.client.post('/foo/', data={'text': 'bar'})
self.assertEqual(response.status_code, 200)
Here is the view foo
which is triggered for that request:
logger = logging.getLogger(__name__)
# decorator to trace enter and exit events
enter_exit_tracer = enter_exit_Tracer(logger)
@enter_exit_tracer
def foo(request):
if request.method == 'POST':
#
print('request.POST:', request.POST)
#
# some stuff
where @enter_exit_tracer
is a decorator to trace entering/exiting a function:
def enter_exit_Tracer(logger):
def middle(f):
def inner(*args, **kwargs):
session_string = args[-1] if 'session_key' in args[-1] else '[]'
logger.debug('%s Enter %s.', session_string, f.__name__)
result = f(*args, **kwargs)
logger.debug('%s Exit %s.', session_string, f.__name__)
return result
return inner
return middle
It turns out that when I add this decorator to foo
function, then the POST
data sent via self.client.post
are actually not passed to foo
. They are missing in the test request - so my test fails:
DEBUG: [] Enter foo.
request.POST: <QueryDict: {}>
ERROR: Invalid form
F
======================================================================
FAIL: test_valid_post_request (textstat.tests.PostRequestTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/Pro/myapp/tests.py", line 111, in test_valid_post_request
self.assertEqual(response.status_code, 200)
AssertionError: 400 != 200
----------------------------------------------------------------------
Ran 1 test in 0.018s
FAILED (failures=1)
We see request.POST: <QueryDict: {}>
and eventually this leads to ERROR: Invalid form
.
At the same time when I do the similar POST
request but via a web browser everything works fine - the form gets populated with data, the web page is rendered ok and @enter_exit_tracer
does its logging as expected.
If I comment out @enter_exit_tracer
decorator then everything works also ok and the test is passed:
request.POST: <QueryDict: {'text': ['bar']}>
.
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
The questions:
- why the
request.POST
data are not passed to the view with the decorator in case ofself.client.post
request? - if anything wrong with the decorator - why then the web request works ok?
- is it possible to keep the decorator and make
self.client.post
pass the data to the view?