Opened 7 years ago
Closed 7 years ago
#30089 closed Bug (invalid)
TestClient doesn't accept data with duplicate keys (SELECT multiple)
| Reported by: | Adam Gilman | Owned by: | nobody |
|---|---|---|---|
| Component: | Testing framework | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When constructing tests for forms with SELECT elements which allow multiple item selection, the test client doesn't accept multiple selections due to the fact it uses dict internally and results in a squashed single key
Failing test
def test_post_multi_select(self): "POST SELECT multiple data to a view" post_data = QueryDict(mutable=True) post_data.update({'value':37}) post_data.update({'value':38}) response = self.client.post('/post_view/', post_data) # Check some response details self.assertEqual(response.status_code, 200) self.assertEqual(response.context['data'], ['37', '38']) self.assertEqual(response.templates[0].name, 'POST Template') self.assertContains(response, 'Data received')
*updated
Change History (10)
comment:1 by , 7 years ago
| Easy pickings: | unset |
|---|
comment:2 by , 7 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
comment:3 by , 7 years ago
Apologies, typo in my original test. Good catch. Updated test in description and failure below:
FAIL: test_post_multi_select (test_client.tests.ClientTest) POST SELECT multiple data to a view ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/dev2/.pyenv/versions/3.7.0/lib/python3.7/unittest/case.py", line 59, in testPartExecutor yield File "/Users/dev2/.pyenv/versions/3.7.0/lib/python3.7/unittest/case.py", line 615, in run testMethod() File "/Users/dev2/Documents/GitHub/django/tests/test_client/tests.py", line 113, in test_post_multi_select self.assertEqual(response.context['data'], ['37', '38']) File "/Users/dev2/.pyenv/versions/3.7.0/lib/python3.7/unittest/case.py", line 839, in assertEqual assertion_func(first, second, msg=msg) File "/Users/dev2/.pyenv/versions/3.7.0/lib/python3.7/unittest/case.py", line 832, in _baseAssertEqual raise self.failureException(msg) AssertionError: '38' != ['37', '38']
comment:4 by , 7 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → new |
comment:5 by , 7 years ago
| Description: | modified (diff) |
|---|
comment:6 by , 7 years ago
I'm not sure the test is right here.
post_view isn't using getList(), so even if POST is a QueryDict, we'll only get the single value...
c = Context({'data': request.POST['value']})
follow-up: 8 comment:7 by , 7 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|---|
| Type: | Uncategorized → Bug |
| Version: | 2.1 → master |
But this fails:
post_data = QueryDict(mutable=True)
post_data.update({'value':37})
post_data.update({'value':38})
self.assertEqual(post_data.getlist('value'), [37, 38])
request = RequestFactory().post('/post_view/', post_data)
self.assertEqual(request.POST.getlist('value'), ['37', '38'])
self.assertEqual(request.POST.getlist('value'), ['37', '38'])
AssertionError: Lists differ: ['38'] != ['37', '38']
So this looks valid.
comment:8 by , 7 years ago
Replying to Carlton Gibson:
request.POST is actual representation of request.body. A post request could have only one parameter of the same name in its body. That's why it returns a single element. I don't think if it's a bug.
comment:9 by , 7 years ago
I didn't look into the cause of the issue but normally a dictionary rather than a QueryDict is used as test client data.
post_data = {'value': [37, 38]} passes the test.
comment:10 by , 7 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
| Triage Stage: | Accepted → Unreviewed |
Then it’s incorrect usage. Good. Thanks both!
It looks like you have a bug in your reported test case, you are updating
post_datatwice with{'value':37}and never including38.Please re-open if you reproduce with
.update({'value':38}).