简体   繁体   中英

How to Replicate Multidict for Flask Post Unit Test Python

So in my flask app, I have a form on the frontend that gets populated with several users. Each user is associated with a checkbox with the name 'selected_user'. On submit, the form is posted through standard HTML form controls (no javascript or manual ajax of any kind).

In the backend, I can parse this using

flask.request.form.getlist('selected_user')

and it returns a list of users as I expect (a user here is itself a dictionary of unique keys and associated values).

Printing out flask.request.form looks like so for example:

ImmutableMultiDict([
  ('_xsrf_token', u'an_xsrf_token_would_go_here'),
  ('selected_user', u'{u\'primaryEmail\': u\'some_value\'}'...),
  ('selected_user', u'{u\'primaryEmail\': u\'some_value\'}'...)])

My problem is, I cannot seem to replicate this format in my unit tests for the life of me. Obviously, I could use some javascript to bundle the checked users on the frontend into an array or whatever and then duplicate that area much easier on the backend, and that may very well be what I end up doing, but that seems like an unnecessary hassle just to make this function testable when it already behaves perfectly in my application.

Here is what I currently have tried in my test, which seems like it should be the correct answer, but it does not work:

mock_users = []
for x in range(0, len(FAKE_EMAILS_AND_NAMES)):
  mock_user = {}
  mock_user['primaryEmail'] = FAKE_EMAILS_AND_NAMES[x]['email']
  mock_user['name'] = {}
  mock_user['name']['fullName'] = FAKE_EMAILS_AND_NAMES[x]['name']
  mock_users.append(mock_user)

data = {}
data['selected_user'] = mock_users

response = self.client.post(flask.url_for('add_user'), data=data,
                            follow_redirects=False)

This gives me an error as follows:

add_file() got an unexpected keyword argument 'primaryEmail'

I've also attempted sending these as query strings, sending data as json.dumps(data), encoding each mock_user as a tuple like this:

data = []
for x in range(0, 3):
  my_tuple = ('selected_user', mock_users[x])
  data.append(my_tuple)

None of these approaches have worked for various other errors. What am I missing here? Thanks ahead of time for any help! Also, sorry if there are an obvious syntax errors as I rewrote some of this for SO instead of copy pasting.

You can create a MultiDict, then make it Immutable:

from werkzeug.datastructures import MultiDict, ImmutableMultiDict

FAKE_EMAILS_AND_NAMES = [
    {'email': 'a@a.com',
     'name': 'a'},
    {'email': 'b@b.com',
     'name': 'b'},
]

data = MultiDict()
for x in range(0, len(FAKE_EMAILS_AND_NAMES)):
  mock_user = {}
  mock_user['primaryEmail'] = FAKE_EMAILS_AND_NAMES[x]['email']
  mock_user['name'] = {}
  mock_user['name']['fullName'] = FAKE_EMAILS_AND_NAMES[x]['name']
  data.add('select_user', mock_user)

data = ImmutableMultiDict(data)

print data

This prints:

ImmutableMultiDict([
    ('select_user', {'primaryEmail': 'a@a.com', 'name': {'fullName': 'a'}}),
    ('select_user', {'primaryEmail': 'b@b.com', 'name': {'fullName': 'b'}})
])

EDIT:

The line data.add... should probably be data.add('selected_user', json.dumps(mock_user)) since it looks like the output you posted is a JSON encoded string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM